Косвенная библиотека Typelib плохо импортируется из Debug dll.
-
02-07-2019 - |
Вопрос
Используя VC2005, мне нужно построить 3 проекта:
- libA (содержит библиотеку типов, в результате получается libA.dll):У IDL есть линия
library libA { ...
- libB (содержит библиотеку типов, импортирующую libA, в результате получается libB.dll):У IDL есть линия
importlib( "libA " );
- libC (импортирует libB):один из исходных файлов содержит
#import <libB.dll>
тот #import <libB.dll>
обрабатывается компилятором следующим образом (согласно документации):
- поиск в каталогах %PATH%
- поиск в каталогах %LIB%
- найдите «дополнительные пути включения» (параметр компилятора /I)
При компиляции libC я вижу, что cl.exe явно может найти libA.dll в пути к исполняемому файлу (с помощью Filemon.exe).
Ошибка ВК C4772:#импорт библиотеки типов с другой зависимостью
Однако пространство имен libA по-прежнему нет найдено, и все ссылки на типы libA заменяются на __missing_type__
(редактировать) Между тем, я обнаружил, что проблема возникает только при использовании отладочных библиотек.
Кто-нибудь видел эту проблему раньше?И решил?
Решение 4
Наконец-то нашел!
В проекте Visual Studio файл A.idl в LibA имел Совместимость с MkTypeLib установка ВКЛ.Это отменило поведение, унаследованное от проекта A.Что еще хуже, в конфигурации отладки он был включен только.
Следствием этого было то, что для каждого
typedef [public] tagE enum { cE1, cE2 } eE;
Это привело к tagE
не определен в результирующей библиотеке типов.Когда LibB это сделал import( "A.dll" )
, все ссылки на tagE
были заменены на __missing_type__
...
Другие советы
Вы явно устанавливаете зависимости проекта?Другими словами, настроили ли вы решение в IDE так, чтобы проект C зависел от проекта B, а проект B зависел от проекта A?
Используете ли вы типы, определенные в libA из libC?Если да, то я думаю, что вам нужно напрямую импортировать libA из libC, чтобы он знал о типах libA.COM не ссылается автоматически на библиотеки типов, на которые ссылается другая библиотека типов.
У меня нет для вас ответа, но у меня был такой опыт несколько раз, и я хотел бы поделиться тем, что я сделал.
В нескольких несвязанных проектах у меня был тот же сценарий.В одном случае я почти неделю пытался устранить зависимости, но в конце концов мне пришлось сократить свои потери, чтобы не отставать от графика.В итоге я использовал #include в файле .tlh (выполнение импорта в DLL сгенерирует их), а затем использовал вызовы API «classic com», чтобы получить указатели на структуры в файлах .tlh.Код не так прост в работе, как если бы вы могли использовать файлы-оболочки, но он работает.
IUnknown *lpUnk;
hr = CoCreateInstance(clsID, NULL, CLSCTX_LOCAL_SERVER, IID_IUnknown, (void **)&lpUnk);
if (FAILED(hr)) throw SomeException;
//
_Application *app; //Address _Application
hr = lpUnk->QueryInterface(__uuidof(_Application), (void **) &app);
lpUnk->Release();
if (FAILED(hr)) throw SomeException;
// Do stuff with the app object
app->Release(); // Then release
Вы можете несколько «устранить» это, используя шаблон оболочки CComPtr, чтобы надежно выполнить выпуск с помощью его деструктора, когда он выходит за пределы области действия:
CComPtr<IUnknown> lpUnk;
hr = CoCreateInstance(clsID, NULL, CLSCTX_LOCAL_SERVER, IID_IUnknown, (void **)lpUnk);
if (FAILED(hr)) throw SomeException;
//
CComPtr<_Application> app; //Address _Application
hr = lpUnk->QueryInterface(__uuidof(_Application), (void **) &app);
if (FAILED(hr)) throw SomeException;
//
// Do stuff with the app object
Обратите внимание, что указатель _Application — это пример использования одной из структур из файла .tlh.