Pregunta

Hola chicos, tengo algunas preguntas rápidas sobre Windows dll.

Básicamente estoy usando los ifdefs para manejar dllexport y dllimport, mi pregunta es en realidad con respecto a la ubicación de dllexports y dllimports, así como la palabra clave externa.

Estoy poniendo dllimports / dllexports en los archivos de encabezado, pero ¿tengo que poner dllexport y dllimports en la definición actual?

¿Qué pasa con typedefs?

¿Pongo el dllimport / dllexport al frente? como en

dllexport typedef map<string, int> st_map

También con respecto a la palabra clave externa, he visto que se usa así:

extern "C" {

dllexport void func1();

}

También he visto que se usa así:

extern dllexport func1();

Uno incluye la "C" y el otro no, mi pregunta es cuál es la diferencia y ¿necesito usarla? Si lo hago, ¿lo uso tanto para dllexport como para dllimport y también tengo que usarlo tanto en las declaraciones del archivo de encabezado como en las definiciones?

Mi proyecto va a ser una biblioteca compartida, contiene varios archivos de clase que quiero exportar, algunos Typdefs que quiero exportar y algunas funciones globales que también quiero exportar todo a un dll.

¿Alguien me ilumina, por favor?

EDITAR:

Bien, pensé que publicaría un pequeño extracto de lo que he hecho, también noto que estoy construyendo la biblioteca para Linux y Windows, así que hago una comprobación para eso:

mydll.h

#ifdef WINDOWS
#   ifdef PSTRUCT_EXPORT
#   define WINLIB __declspec(dllexport)
#   else
#   define WINLIB __declspec(dllimport)
#   endif
#else
#  define WINLIB
#endif

WINLIB void funct1();

Ahora en el código fuente:

mydll.cpp

#define PSTRUCT_EXPORT

void funct1() <---- do i need to add WINLIB in front of it? 
                      Or is doing it in the header enough?
¿Fue útil?

Solución

Primero, no necesita importar o exportar typedefs. Mientras estén en los archivos de encabezado que usan ambos lados, eres bueno. Es necesario importar / exportar funciones y definiciones de clase.

Presumiblemente, usa los mismos archivos de encabezado tanto para el código de importación como para el de exportación, por lo que podría hacer un poco de magia de archivo para definir una macro de preprocesador en cada lado, y luego hacer algo como esto:

#if defined( LIBRARY_CODE )
#define MYAPI __declspec(dllexport)
#else
#define MYAPI __declspec(dllimport)
#endif

extern MYAPI void func1();
class MYAPI MyClass {
    ...
};

Con respecto a las funciones C vs. C ++, puede hacer esto:

#if defined( __cplusplus__ ) // always defined by C++ compilers, never by C
#define _croutine "C"
#else
#define _croutine
#endif

extern _croutine void function_with_c_linkage();

Asegúrese de importar este archivo de encabezado desde su archivo fuente C ++ (que contiene la implementación de esta función) o el compilador no sabrá darle el enlace C.

Otros consejos

  1. typedefs NO necesita un dllimport / dllexport, es solo una definición
  2. dllimport / dllexport no son estándar, piense en definir una macro para otras plataformas / compiladores
  3. también cuide la convención de llamada (cdecl, stdcall, ...) utilizada, de lo contrario tendrá problemas (si necesita ser interoperable con el uso de Visual basic stdcall)
  4. encerrar dentro de "C" externo para que su lib pueda usarse desde los programas de C ++, use #ifdef __cplusplus para mantenerla solo visible en C ++.

Eche un vistazo a diferentes bibliotecas OpenSource. Allí encontrará muchos ejemplos sobre cómo hacer un buen encabezado de biblioteca. Podría haber problemas con la decoración de nombres en el caso de C ++ sin la "C" externa.

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