2012-05-02 13 views
5

Según el título, intento crear una DLL usando C y vincularla desde un proyecto de C++. Leí y seguí diferentes tutoriales en Internet, pero cada vez me falta algo y no entiendo qué.Crear una DLL en C y vincularla desde un proyecto de C++

Aquí es lo que hice, paso a paso:

he creado un nuevo proyecto Win32, llamado testlib, a continuación, desde el asistente, he elegido "DLL" y "proyecto vacío".

añade una cabecera:

//testlib.h 

#include <stdio.h> 

__declspec(dllexport) void hello(); 

añade una fuente; ya que yo quiero que sea una fuente de C leí que debería cambiar el nombre del archivo .cpp simplly en .c, por lo

//testlib.c 

#include "testlib.h" 

void hello() { 
    printf("DLL hello() called\n"); 
} 

Construir tuvo éxito.

Ahora me gustaría utilizar mi dll útil en otro proyecto.

Luego: nuevo proyecto (testlibUse). Esta vez seleccioné "Proyecto vacío".
No hay necesidad de añadir una cabecera, que acaba de crear una fuente de CPP

//main.cpp 
#include <testlib.h> 

int main() { 
    hello(); 
} 

continuación:

  • añadí la ruta de la carpeta en la que está testlib.dll en Propiedades-> VC++ directorios-> directorios ejecutables

  • que añade la ruta de la carpeta en la que está testlib.h en Propiedades-> VC++ directorios-> Incluir directorios

  • he añadido el camino a testlib.lib (extensión incluido) en Propiedades-> Linker-> Input-> dependencias adicionales

he tratado de construir, pero tengo un error de vinculador:

LINK : C:\path\testlibUse\Debug\testlibUse.exe not found or not built by the last incremental link; performing full link
main.obj : error LNK2019: unresolved external symbol "void __cdecl hello(void)" ([email protected]@YAXXZ) referenced in function _main
C:\path\testlibUse\Debug\testlibUse.exe : fatal error LNK1120: 1 unresolved externals

Si vuelvo a testlib, cambio el nombre testlib.c en testlib.cpp y reconstruyo el dll, entonces puedo construir testlibUse pero aparece el error "dll no encontrado" en el tiempo de ejecución.

Intenté también cambiar las configuraciones de ambos proyectos en "Versión" (cambiando la ruta donde sea necesario), pero nada cambió.

Perdón por la larga publicación, pero creo que fue necesario escribir exactamente lo que hice.

¿Alguna sugerencia?

Además, ¿hay algún parámetro de configuración que deba cambiar si quiero usar mi dll en un proyecto de Qt?

Respuesta

9

Usted tiene varios problemas:

  1. El archivo de cabecera debe marcar las funciones que fueron exportados al ser compilado en el archivo DLL pero importados cuando es compilado por un usuario de la biblioteca.
  2. El archivo de cabecera debe envolver las declaraciones de funciones en un bloque de extern "C" al ser compilado como C++ para asegurarse de que los nombres no reciben destrozado
  3. La DLL no está en la ruta de búsqueda de su ejecutable, por lo que no puede ser encontrado en tiempo de ejecución.

Para el montaje (1) y (2), vuelve a escribir el encabezado de esta manera:

#ifdef __cplusplus 
extern "C" { 
#endif 

// Assume this symbol is only defined by your DLL project, so we can either 
// export or import the symbols as appropriate 
#if COMPILING_MY_TEST_DLL 
#define TESTLIB_EXPORT __declspec(dllexport) 
#else 
#define TESTLIB_EXPORT __declspec(dllimport) 
#endif 

TESTLIB_EXPORT void hello(); 
// ... more function declarations, marked with TESTLIB_EXPORT 

#ifdef __cplusplus 
} 
#endif 

Para el montaje (3), copiar el archivo DLL en la misma carpeta que el archivo ejecutable. La configuración de "directorios ejecutables" que está configurando no afecta la búsqueda de DLL: consulte MSDN para obtener una descripción detallada de cómo se buscan las DLL. La mejor solución para usted es copiar su archivo DLL en el directorio donde vive su archivo ejecutable. Puede hacerlo manualmente o agregar un paso posterior a la compilación en su proyecto que lo haga por usted.

1

Parece que necesita asegurarse de que el compilador no mangle el nombre del símbolo en la compilación cpp. Debería poder agregar un extern "C" a la definición en testlib.h:

#ifdef __cplusplus 
extern "C" 
#endif 
__declspec(dllexport) void hello(); 
+0

pero me da un error "No se encontró dll" en tiempo de ejecución ... no fue suficiente para agregar la ruta de acceso al archivo DLL en Propiedades-> VC++ directorios-> directorios ejecutables? – Saphrosit

+0

@Saphrosit: No, a mi leal saber y entender, eso no afectaría el funcionamiento de la aplicación. Lea la descripción en esa página de propiedades; afecta el hallazgo de binarios al construir el proyecto. Necesita el archivo DLL que se va a encontrar (por ejemplo, a través de la variable de entorno PATH) en tiempo de ejecución. –

2

Debe extern "C" el incluir:

+0

Generación exitosa pero aparece el error "dll no encontrado" en el tiempo de ejecución ... ¿No fue suficiente para agregar la ruta al dll en Propiedades-> Directorios VC++-> Directorios ejecutables? – Saphrosit

1

Aquí hay un método para su archivo de cabecera C que podría ser incluido por C++. Asegúrese de establecer TESTLIB_EXPORTS solo en la configuración del preprocesador DLL. En proyectos que incluyen este encabezado para usar el DLL, el encabezado declarará las funciones como importaciones en lugar de exportaciones.

El protector __cplusplus le dirá al compilador que importe sus funciones usando la decoración del nombre C en lugar de la decoración del nombre C++.

#include <stdio.h> 

#ifdef TESTLIB_EXPORTS 
#define TESTLIB_API __declspec(dllexport) 
#else 
#define TESTLIB_API __declspec(dllimport) 
#endif 

#ifdef __cplusplus 
extern "C" { 
#endif 

TESTLIB_API void hello(); 
/* other prototypes here */ 

#ifdef __cplusplus 
} 
#endif 
Construir éxito