Por que não posso usar __declspec(dllexport) para exportar DllGetClassObject() a partir de uma DLL de COM?

StackOverflow https://stackoverflow.com/questions/3460533

  •  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.

Foi útil?

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.

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