пятница, 14 марта 2014 г.

tlbimp.exe и целевая версия .NET Framework

ObjectARX SDK содержит некоторый набор TLB файлов. Для некоторых из них приходится генерировать управляемую обёртку "вручную" (причина указана ниже), посредством утилиты tlbimp.exe (если нужная обёртка изначально отсутствует). Обозначенная утилита содержит некоторый набор ключей для конфигурирования конечного результата. Однако одной, очень важной настройки, всё же не хватает...

На моём рабочем компьютере установлены MS Visual Studio 2005-2012 и .NET Framework 2.0 - 4.5. В первый раз я столкнулся с необходимостью прибегать к "ручному" использованию утилиты tlbimp.exe, когда в MS Visual Studio 2012 был создан проект плагина AutoCAD 2010 (целевая платформа .NET 3.5, разрядность x64), но при этом мне не далось подключить ссылки на acax18ENU.tlb и axdb18enu.tlb. (на самом деле именно эти tlb файлы нет никакой нужды подключать, т.к. вместо них нужно подключать библиотеки Interop, но в данном случае на их примере я показываю проблему, которая может возникнуть при использовании утилиты tlbimp.exe). "За кулисами", при подключении TLB файлов IDE обычно для них автоматически генерирует управляемые обёртки, но в данном случае этого не произошло:


Насколько мне известно, причиной подобной ошибки может быть некорректная регистрация COM в реестре, либо вообще отсутствие в реестре этой информации.

Та же самая ситуация для AutoCAD 2010 наблюдалась и в MS Visual Studio 2005-2010. В виду этого приходится генерировать DLL обёртку при помощи "ручного" запуска утилиты tlbimp.exe. Однако и тут не всё так красиво, как хотелось бы: к сожалению, в утилите tlbimp.exe нет возможности указать целевую версию платформы .NET, для которой следует генерировать обёртку.
Я пытался сгенерировать обёртку для нужных мне TLB файлов из консолей разных версий MS Visual Studio следующим образом:

tlbimp "C:\SDK\Autodesk\AutoCAD\ObjectARX 2010\inc-x64\acax18ENU.tlb" /out:"C:\SDK\Autodesk\AutoCAD\ObjectARX 2010\inc-x64\acax18ENU.Interop.dll" /namespace:AutoCAD /machine:x64

tlbimp "C:\SDK\Autodesk\AutoCAD\ObjectARX 2010\inc-x64\axdb18enu.tlb" /out:"C:\SDK\Autodesk\AutoCAD\ObjectARX 2010\inc-x64\axdb18enu.Interop.dll" /namespace:AXDBLib /machine:x64

Примечание:
При подключении этих оболочек к проекту, необходимо их свойство Copy Local устанавливать в TRUE, поскольку они сгенерированы нами и будут отсутствовать в каталоге AutoCAD.

Если использовать консоль VS 2010 или VS 2012, то обёртка будет создана для .NET 4.0. Однако в AutoCAD 2010 использует .NET 3.5, поэтому данный результат мне не подходит...

Получить нужный результат мне удалось лишь воспользовавшись консолью VS 2008.

На моей машинке, в составе установленных SDK

утилиту tlbimp.exe мне удалось найти в каталогах:
  • C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools
  • C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools
  • C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin
Кроме того, утилита была найдена и в каталоге
  • C:\Program Files (x86)\Microsoft Visual Studio 8\SDK\v2.0\Bin
В обозначенных выше первых трёх каталогах, я пробовал создавать конфигурационный файл tlbimp.exe.config следующего содержимого:

<?xml version="1.0" encoding="utf-8"?>
   <startup>
   <supportedRuntime version="v2.0.50727"/>
</startup>


Затем из cmd.exe, перейдя в каталог указанной утилиты, запустил такую команду:

C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools>tlbimp
 "D:\SDK\Autodesk\AutoCAD\ObjectARX 2010\inc-x64\acax18ENU.tlb" /out:"D:\SDK\Autodesk\AutoCAD\ObjectARX 2010\inc-x64\acax18ENU.Interop.dll" /namespace:AutoCAD /machine:x64
Не удалось запустить приложение, поскольку его параллельная конфигурация неправильна. Дополнительные сведения содержатся в журнале событий приложений или используйте программу командной строки sxstrace.exe для получения дополнительных сведений.


Обозначенный выше результат наблюдался для версий v8.1A и v8.0A. Для версии v7.0A в перенастройке не было необходимости, т.к. на выходе и так получается библиотека для .Net 2.0.
Если удалить созданный мною конфигурационный файл, то для v8.1A и v8.0A операция так же проходит успешно, но на выходе, конечно же, получаем библиотеку для .Net 4.0:

C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools>
C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools>tlbimp
 "D:\SDK\Autodesk\AutoCAD\ObjectARX 2010\inc-x64\acax18ENU.tlb" /out:"D:\SDK\Autodesk\AutoCAD\ObjectARX 2010\inc-x64\acax18ENU.Interop.dll" /namespace:AutoCAD /machine:x64
Microsoft (R) .NET Framework Type Library to Assembly Converter 4.0.30319.33440
Copyright (C) Microsoft Corporation.  All rights reserved.

TlbImp : warning TI3019 : Interface 'IAcadShadowDisplay' is marked as [dual], but does not derive from IDispatch. It will be converted as an IUnknown-derived interface.
TlbImp : Type library imported to D:\SDK\Autodesk\AutoCAD\ObjectARX 2010\inc-x64
\acax18ENU.Interop.dll


Вывод:
Если необходимо сгенерировать управляемые DLL обёртки на основе файлов TLB, то для разных целевых версий .NET следует использовать утилиту tlbimp.exe из разных Windows SDK:
  • SDK v7.0A - для .NET 2.0, 3.0, 3.5 SP1
  • SDK v8.1A или v8.0A - для .NET 4.0, 4.5, 4.5.1

Комментариев нет: