Pregunta

Estoy atascado en una solución a un legado Visual C++ 6 de la aplicación.En la DLL de C++ fuente que he puesto

extern "C" _declspec(dllexport) char* MyNewVariable = 0;

que se traduce en MyNewVariable mostrando (muy bien decorado) en la tabla de exportación (como se muestra por dumpbin /exportaciones blah.dll).Sin embargo, no puedo entender cómo declarar la variable, por lo que puedo acceder a ella, en un C archivo de origen.He intentado varias cosas, incluyendo

_declspec(dllimport) char* MyNewVariable;

pero eso solo me da un error del vinculador:

externos sin resolver símbolo "__declspec(dllimport) char * MyNewVariable" (__imp_?MyNewVariable@@3PADA)

extern "C" _declspec(dllimport) char* MyNewVariable;

según lo sugerido por Tony (y como he intentado antes) resultados en diferentes espera de la decoración, pero aún no se ha quitado:

sin resolver símbolo externo __imp__MyNewVariable

¿Cómo puedo escribir la declaración a fin de que la DLL de C++ variable es accesible desde la C aplicación?


La Respuesta

Como identificado por botismarius y otros (muchas gracias a todos), necesitaba de enlace con el archivo DLL .lib.Para evitar que el nombre de ser mutilado necesitaba a declarar (en el código fuente de C) sin decoradores, lo que significa que tuve que usar el .archivo lib.

¿Fue útil?

Solución

debe vincular contra la lib generado después de compilar la DLL.En las opciones del enlazador del proyecto, se debe agregar el .lib archivo.Y sí, también debe declarar la variable como:

extern "C" { declspec(dllimport) char MyNewVariable; }

Otros consejos

extern "C" es la forma de quitar la decoración - se debe trabajar para el uso:

extern "C" declspec(dllimport) char MyNewVariable;

o si quieres un encabezado, que puede ser utilizado por C++ o C (con modificador /TC)

#ifdef __cplusplus
extern "C" {
#endif
declspec(dllimport) char MyNewVariable;
#ifdef __cplusplus
}
#endif

Y, por supuesto, el enlace con la biblioteca de importación generada por la dll de hacer la exportación.

No estoy seguro de que downmodded botismarius, porque él está en lo correcto.La razón es la .lib generado es la biblioteca de importación que hace que sea fácil de simplemente declarar la variable externa/función con __declspec(dllimport) y sólo lo utilizan.La biblioteca de importación simplemente automatiza el necesario LoadLibrary() y GetProcAddress() las llamadas.Sin ella, usted necesita llamar a estas manualmente.

Ambos están a la derecha.El hecho de que el mensaje de error que describe __imp_?MyNewVariable@@3PADA significa que está buscando para la decoración de nombre, por lo que el extern "C" es necesario.Sin embargo, la vinculación con la biblioteca de importación es también necesario o usted acaba de conseguir un enlace distinto de error.

@Graeme:En eso tienes razón, demasiado.Creo que la "C" del compilador que el OP está utilizando no es exigir estándar C99, pero compilar como C++, lo que renombrar los nombres.Un verdadero compilador de C no entender la "C" parte de la extern "C" la palabra clave.

En el dll de código fuente usted debe tener esta aplicación con el fin de que el .archivo lib las exportaciones el símbolo:

extern "C" _declspec(dllexport) char* MyNewVariable = 0;

El c cliente debe utilizar un encabezado con esta declaración, de modo que el código de cliente se importación el símbolo:

extern "C" _declspec(dllimport) char* MyNewVariable;

Este encabezado provocará un error de compilación si #include-ed en la dll de código fuente, por lo que se suele poner en un encabezado de exportación que se utiliza sólo para las funciones exportadas y sólo por los clientes.

Si usted lo necesita, usted también puede crear un "universal" de cabecera que puede ser incluido en cualquier lugar que se parece a esto:

#ifdef __cplusplus
extern "C" {
#endif
#ifdef dll_source_file
#define EXPORTED declspec(dllexport) 
#else
#define EXPORTED declspec(dllimport) 
#endif dll_source_file
#ifdef __cplusplus
}
#endif

EXPORTED char* MyNewVariable;

A continuación, el archivo dll de código fuente se parece a esto:

#define dll_source_code 
#include "universal_header.h"

EXPORTED char* MyNewVariable = 0;

Y el cliente se parece a esto:

#include "universal_header.h"
...
MyNewVariable = "Hello, world";

Si usted hace esto mucho, el monstruo #ifdef en la parte superior se puede ir en export_magic.h y universal_header.h se convierte en:

#include "export_magic.h"

EXPORTED char *MyNewVariable;

Yo nunca he usado _declspec(dllimport) cuando yo estaba en la programación de Windows.Usted debe ser capaz de simplemente declarar

extern "C" char* MyNewVariable;

y el enlace a la .libb creado cuando una DLL que se compiló.

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