¿Por qué no puedo utilizar __declspec (dllexport) para exportar DllGetClassObject () desde un COM DLL?

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

  •  27-09-2019
  •  | 
  •  

Pregunta

Estoy desarrollando un COM DLL y tratando de exportar el método DllGetClassObject () con el __ declspec (dllexport) .

Aquí está mi declaración:

extern "C" HRESULT __declspec(dllexport) __stdcall DllGetClassObject(REFCLSID rclsid, 
                                                             REFIID riid, void** ppv)

Pero seguí obtener este error:

error C2375: 'DllGetClassObject' : redefinition; different linkage

Así que trato de revisar toda la ocurrencia de las definiciones DllGetClassObject. Así encontrado el siguiente en el OBJBASE.H .

STDAPI  DllGetClassObject(__in REFCLSID rclsid, __in REFIID riid, __deref_out LPVOID FAR* ppv);

la STDAPI resulta ser la siguiente:

#define STDAPI                  EXTERN_C HRESULT STDAPICALLTYPE

En otras palabras, es como sigue:

#define STDAPI                  extern "C" HRESULT __stdcall

De acuerdo con MSDN :

  

funciones de exportación a la   __declspec (dllexport) debe aparecer a la izquierda de la   palabra clave de llamadas de la convención, si una   palabra clave se especifica.

Pero mi declaración mencionó antes simplemente no funcionó.

Lo mismo sucede con COM DLL Have a exportar sus métodos con un def archivo?


Actualización 1

Probé mi declaración con un nombre de método diferente, como se muestra abajo:

extern "C" HRESULT __declspec(dllexport) __stdcall f()
{
    return S_OK;
}

Y este método se ha exportado correctamente. Por lo que estos especificadores podrían utilizarse juntos. Parece que el Visual C ++ toma compilador STDAPI y extern "C" __declspec HRESULT (dllexport) __stdcall que no es compatible.

¿Fue útil?

Solución

Este problema se produce porque creo que una función __stdcall (para 32 bits construye) normalmente está decorado con un prefijo de subrayado y un postfix @count. Pero si la función también se marca como __declspec(dllexport) se añaden decoraciones adicionales (__imp, creo).

podría ser capaz de evitar el uso de un archivo .def con la siguiente pragma, si estás dispuesto a vivir con el pragma (creo que me gustaría ir para el archivo .def):

#pragma comment( linker, "/export:DllGetClassObject=_DllGetClassObject@12" )

Tenga en cuenta que para una acumulación x64, puede que tenga que compilar condicionalmente el pragma, que creo que sería la siguiente:

#pragma comment( linker, "/export:DllGetClassObject" )

Otros consejos

No compilar debido a que la primera declaración en OBJBASE.H no tiene el atributo __declspec (dllexport). No se puede agregar que en la definición. no ayudará de todos modos, la decoración de nombres no es apropiado. Michael mostró lo que debe hacer al respecto.

Voy a salir en una extremidad y decir que sí.

A pesar de Visual Studio 2008 genera automáticamente el archivo .def para ATL .dll proyectos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top