Pergunta

Usando VC2005, eu tenho 3 projectos para construir:

  • Liba (contém um typelib, resultados no libA.dll): IDL tem uma linha library libA { ...
  • libB (contém um typelib importando Liba, resultados no libB.dll): IDL tem uma linha importlib( "libA " );
  • libc (importações libB): um dos arquivos de origem contém #import <libB.dll>

o #import <libB.dll> é tratado pelo compilador da seguinte maneira (de acordo com documentação):

  1. diretórios de busca de% PATH%
  2. diretórios de busca de% LIB%
  3. procurar o "adicional incluir caminhos" (/ I opção do compilador)

Ao compilar libc, eu posso ver que cl.exe claramente é capaz de encontrar o libA.dll no caminho executável (utilizando Filemon.exe)

VC erro C4772: #import de typelib com outra dependência

No entanto, ainda o namespace Liba é não encontrado e todas as referências a tipos Liba são substituídos por __missing_type__

(edit) Enquanto isso, eu descobri que o problema só aparece quando usando as DLLs de depuração.

Alguém viu esse problema antes? E resolveu isso?

Foi útil?

Solução 4

Finalmente encontrei-o!

No projeto Visual Studio, o arquivo A.idl em Liba teve a MkTypeLib Compatível ajuste ON. Este anulou o comportamento herdado do projeto A. Para piorar as coisas, era apenas ON na configuração de depuração.

A consequência foi que, para cada

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

Isso resultou na tagE não ser definida no typelib resultante. Quando LibB fez isso de import( "A.dll" ), todas as referências a tagE foram substituídos por __missing_type__ ...

Outras dicas

Você está definindo explicitamente as dependências do projeto? Em outras palavras se você configurar a solução no IDE para que o projeto C depende de projeto B, e o projeto B depende de projeto de A?

Você está usando tipos definidos no Liba de libc? Se assim for, eu acho que você precisa para importar diretamente Liba da libc para que ele sabe sobre os tipos de Liba. COM não faz referência automaticamente as bibliotecas de tipos que se estão referenciados por outra biblioteca tipo.

Eu não tenho uma resposta para você, mas eu tive essa experiência várias vezes e eu gostaria de compartilhar o que eu fiz.

Em vários projetos não relacionados, tive o mesmo cenário. Tentei por quase uma semana em um caso para resolver as dependências, mas eu finalmente tive que cortar minhas perdas, a fim de permanecer na programação. Acabei usando um #include no arquivo .tlh (realizando uma importação na DLL irá gerar estes), em seguida, usando "clássico COM" chamadas de API para obter ponteiros para as estruturas dentro dos arquivos .tlh. O código não é tão limpa para trabalhar com como seria se você poderia usar os ficheiros de mensagens publicitárias, mas funciona.

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

Você pode tanto "de-enfear" isso usando o CComPtr invólucro modelo para fazer a liberação de forma confiável a partir com o seu destruidor quando se sai do escopo:

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

Note que o ponteiro _Application é um exemplo de uso de uma das estruturas de um arquivo .tlh.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top