Непрямой Typelib плохо импортируется из Debug dll - PullRequest
2 голосов
/ 26 сентября 2008

Используя VC2005, у меня есть 3 проекта для сборки:

  • libA (содержит библиотеку типов, приводит к libA.dll): в IDL есть строка library libA { ...
  • libB (содержит библиотеку типов, импортирующую libA, приводит к libB.dll): в IDL есть строка importlib( "libA " );
  • libC (импорт libB): один из исходных файлов содержит #import <libB.dll>

#import <libB.dll> обрабатывается компилятором следующим образом (согласно документации):

  1. поиск в каталогах% PATH%
  2. поиск в каталогах% LIB%
  3. поиск по "дополнительным путям включения" (опция компилятора / I)

При компиляции libC я вижу, что cl.exe явно может найти libA.dll по пути к исполняемому файлу (используя Filemon.exe)

Ошибка VC C4772: # импорт typelib с другой зависимостью

Тем не менее, пространство имен libA не найдено, и все ссылки на типы libA заменены на __missing_type__

(edit) Тем временем я обнаружил, что проблема появляется только при использовании отладочных библиотек.

Кто-нибудь видел эту проблему раньше? И решил это?

Ответы [ 4 ]

1 голос
/ 23 марта 2009

Наконец-то нашел!

В проекте Visual Studio для файла A.idl в LibA было установлено значение MkTypeLib Compatible . Это отменило поведение, унаследованное от проекта А. Что еще хуже, он был включен только в конфигурации отладки.

Следствием было то, что для каждого

typedef [public] tagE enum { cE1, cE2 } eE;

Это привело к тому, что tagE не был определен в результирующей библиотеке типов. Когда LibB сделал это import( "A.dll" ), все ссылки на tagE были заменены на __missing_type__ ...

1 голос
/ 27 октября 2008

Используете ли вы типы, определенные в libA из libC? Если это так, я думаю, что вам нужно напрямую импортировать libA из libC, чтобы он знал о типах libA. COM автоматически не ссылается на библиотеки типов, на которые ссылается другая библиотека типов.

1 голос
/ 28 октября 2008

У меня нет ответа для вас, но у меня был этот опыт несколько раз, и я хотел бы поделиться тем, что я сделал.

В нескольких не связанных проектах у меня был один и тот же сценарий. Я пытался разрешить зависимости почти неделю, но в итоге мне пришлось сократить свои потери, чтобы не отставать от графика. В итоге я использовал #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.

1 голос
/ 26 сентября 2008

Вы явно устанавливаете зависимости проекта? Другими словами, вы настроили решение в IDE так, чтобы проект C зависел от проекта B, а проект B зависел от проекта A?

...