Por que não posso usar __declspec(dllexport) para exportar DllGetClassObject() a partir de uma DLL de COM?
-
27-09-2019 - |
Pergunta
Estou desenvolvendo uma dll de COM e tentando exportar o DllGetClassObject() o método com o __declspec(dllexport).
Aqui está a minha declaração:
extern "C" HRESULT __declspec(dllexport) __stdcall DllGetClassObject(REFCLSID rclsid,
REFIID riid, void** ppv)
Mas eu continuei a receber este erro:
error C2375: 'DllGetClassObject' : redefinition; different linkage
Então, eu vou tentar de todas as ocorrência da DllGetClassObject definições.Assim, encontrado o seguinte na ObjBase.h.
STDAPI DllGetClassObject(__in REFCLSID rclsid, __in REFIID riid, __deref_out LPVOID FAR* ppv);
o STDAPI acaba por ser como este:
#define STDAPI EXTERN_C HRESULT STDAPICALLTYPE
em outras palavras, é como este:
#define STDAPI extern "C" HRESULT __stdcall
De acordo com a MSDN:
Para funções de exportação, o __declspec(dllexport) deve aparecer à esquerda do chamado palavra-chave convenção, se uma palavra-chave especificada.
Mas a minha declaração mencionada antes simplesmente não funciona.
Isso faz COM DLL tem que exportação de seus métodos com um def arquivo?
Atualização 1
Eu testei a minha declaração com um diferente nome do método, mostrado abaixo:
extern "C" HRESULT __declspec(dllexport) __stdcall f()
{
return S_OK;
}
E esse método foi exportado com êxito.Então, esses especificadores poderiam ser usados juntos.Parece que o compilador de Visual C++ leva STDAPI e extern "C" HRESULT __declspec(dllexport) __stdcall como não é compatível.
Solução
Este problema ocorre porque eu acho uma __stdcall função (para a versão de 32 bits cria) é normalmente decorado com um carácter de sublinhado de um prefixo e de um @count
postfix.Mas se a função é marcado também como __declspec(dllexport)
decorações adicionais são adicionados (__imp
, Eu acho).
Você pode ser capaz de evitar o uso de uma .arquivo def com o pragma seguinte, se você está disposto a viver com o pragma (eu acho que gostaria de ir para o .arquivo def):
#pragma comment( linker, "/export:DllGetClassObject=_DllGetClassObject@12" )
Observe que, para um x 64 construir, você pode ter que compilar condicionalmente o pragma, que eu acho que seria:
#pragma comment( linker, "/export:DllGetClassObject" )
Outras dicas
Ele não compila porque a declaração original em objbase.h não tem o __declspec(dllexport) atributo.Você não pode adicioná-lo na definição.Não ajudar de qualquer maneira, o nome de decoração não é apropriado.Michael mostrou-lhe o que fazer sobre isso.
Eu vou sair em um membro e dizer sim.
Até mesmo o Visual Studio 2008 gera automaticamente o .arquivo def para COM ATL .projectos de dll.