Construyendo DLLs con Microsoft Visual C++ para su uso en LabVIEW

Actualizado el Nov 26, 2020

Ambiente

Software

  • LabVIEW

Otros

  • Microsoft Visual Studio

El entorno de desarrollo integrado (IDE) Visual C ++ (MSVC) de Microsoft puede resultar abrumador si el programador nunca lo ha utilizado. Este documento está diseñado para ayudar a quienes deseen compilar un DLL para usar con LabVIEW.

Nota : este documento se escribió con MSVC 2010

Crear un proyecto DLL

Siga los pasos del tutorial de Microsoft para crear una DLL de C ++: Tutorial: Cree y use su propia biblioteca de vínculos dinámicos (C ++)
  1. En Visual Studio, seleccione Archivo » Nuevo proyecto para abrir el cuadro de diálogo Nuevo proyecto. En la lista de Plantillas de Visual C ++ , seleccione Proyecto Win32 , asigne un nombre a su proyecto y haga clic en Aceptar .
  1. En el siguiente cuadro de diálogo, puede ver que la configuración actual del proyecto es la Aplicación de Windows. Haga clic en Siguiente para cambiar el tipo de aplicación a DLL .


  1. Seleccione Finalizar para crear la DLL. MSVC crea un proyecto DLL con un archivo de origen ( .cpp ), que tiene el mismo nombre que el proyecto. También genera un archivo stdafx.cpp . El archivo stdafx.cpp es necesario, pero generalmente no es necesario editarlo.

Editar el archivo de origen

  1. Cada archivo DLL debe tener una función DllMain , que es el punto de entrada para la biblioteca. Determine sus necesidades de función DllMain y edite la función si es necesario.

  • A menos que deba realizar una inicialización específica de la biblioteca, el DllMain predeterminado que creó MSVC es suficiente. Observe que esta función no hace nada.
BOOL APIENTRY DllMain (HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved)
{
return TRUE;
}
  • Si se requiere una inicialización de la biblioteca, es posible que necesite un DllMain más completo:
BOOL WINAPI DllMain (
HINSTANCEhinstDLL, // maneja el módulo DLL
DWORD fdwReason, // motivo para llamar a la función
LPVOID lpReserved) // reservado
{
// Realizar acciones basadas en el motivo de la llamada.
cambiar (fdwReason)
{
case DLL_PROCESS_ATTACH:
// Inicializar una vez para cada nuevo proceso.
// Devuelve FALSE para fallar la carga de la DLL.
break;

case DLL_THREAD_ATTACH:
// Realiza una inicialización específica del subproceso.
break;

case DLL_THREAD_DETACH:
// Realizar una limpieza específica de subprocesos.
brake;

case DLL_PROCESS_DETACH:
// Realice cualquier limpieza necesaria.
brake;
}
return TRUE;
}
  1. Una vez que la función DllMain esté completa, escriba las rutinas a las que desea acceder desde la DLL. Por ejemplo:
// Declaraciones de funciones
int GetSphereSAandVol (radio double, duoble * sa, double * vol);
double GetSA (double radio);
double GetVol (double radio);

...

int GetSphereSAandVol (radio double, double * sa, double * vol)
// Calcula el área de la superficie y el volumen de una esfera con un radio dado
{
si (radio <0)
false return; // devuelve falso (0) si el radio es negativo
* sa = GetSA (radio);
* vol = GetVol (radio);
return true;
}

double GetSA (double radio)
{
return 4 * M_PI * radio * radio;
}

double GetVol (double radio)
{
return 4.0 / 3.0 * M_PI * pow (radio, 3.0);
}
  1. Para que la DLL se compile correctamente, debe declarar la función pow (es decir, potencia, pow (x, y) es equivalente a x ^ y) y la constante M_PI (es decir, 3,14159). Haga esto insertando dos líneas de código debajo #include "stdafx.h" en la parte superior del archivo . archivo cpp . El código debería verse como sigue:


#include "stdafx.h"
#include "math.h" // biblioteca que define la función pow
#define M_PI 3.14159 // declaramos nuestra constante M_PI


En este punto, puede compilar y vincular la DLL. Sin embargo, si lo hace, la DLL no exportará ninguna función y, por lo tanto, no será realmente útil.

Exportación de símbolos

Para acceder a las funciones dentro de la DLL, es necesario decirle al compilador que exporte los símbolos deseados. Sin embargo, primero debe abordar el problema de la decoración de nombres de C ++. MSVC compila su fuente como C ++ si tiene una extensión. cpp o. extensión cxx . Si el archivo de origen tiene extensión. c , luego MSVC lo compila como C. Si compila su archivo como C ++, los nombres de las funciones normalmente se decoran en el código de salida. Esto puede ser problemático porque el nombre de la función tiene caracteres adicionales agregados. Para evitar este problema, declare la función como 'extern "C"' en la declaración de la función, de la siguiente manera:

extern "C" int GetSphereSAandVol (radio double, double * sa, double * vol);

Esto evita que el compilador decore el nombre con decoraciones C ++.
Advertencia : sin la decoración de C ++, las funciones polimórficas no son posibles.

Cuando termine con las decoraciones de C ++, puede exportar las funciones. Hay dos métodos para informar al vinculador qué funciones exportar. El primero, y el más simple, es usar la etiqueta __declspec (dllexport) en el prototipo de función para cualquier función que desee exportar. Para hacer esto, agregue la etiqueta a la declaración y definición, de la siguiente manera:

extern "C" __declspec (dllexport) int GetSphereSAandVol (radio double, double * sa, double * vol);
...
__declspec (dllexport) int GetSphereSAandVol (radio double, double * sa, double * vol)
{
...
}


El segundo método es utilizar un. def para declarar explícitamente qué funciones exportar. El archivo def es un archivo de texto que contiene información que el vinculador usa para decidir qué exportar. Tiene el siguiente formato:

LIBRARY <Nombre para usar dentro de DLL>
DESCRIPTION "<Descripción>"
EXPORTS
<First Export> @ 1
<Second Export> @ 2
<Third Export> @ 3
...


Para el ejemplo de DLL, el archivo def se verá así:
LIBRARY EasyDLL
DESCRIPTION "Hace algunas cosas de esfera".
EXPORTS
GetSphereSAandVol @ 1


Si ha creado correctamente su proyecto DLL, el vinculador busca automáticamente un archivo. def del mismo nombre que el proyecto en el directorio del proyecto. Para cambiar esta opción, seleccione Proyecto » Propiedades . En la carpeta del vinculador , haga clic en la página de propiedades de entrada y modifique la propiedad del archivo de definición del módulo a / DEF: <nombre de archivo> .def .

Consulte también Exportación de Microsoft desde una DLL con archivos DEF


Especificar la convención de llamada

Lo último que puede necesitar hacer antes de compilar la DLL es especificar la convención de llamada para las funciones que desea exportar. Por lo general, hay dos opciones: convenciones de llamadas de C o convenciones de llamadas estándar, también llamadas Pascal y WINAPI. La mayoría de las funciones de DLL usan convenciones de llamada estándar, pero LabVIEW puede llamar a cualquiera de ellas.

Para especificar las convenciones de llamadas de C, no es necesario hacer nada. Este es el valor predeterminado a menos que especifique lo contrario en Proyecto »Propiedades» C / C ++ »Avanzado . Si desea declarar explícitamente la función como una llamada C, use la palabra clave __cdecl en la declaración y definición de la función:

extern "C" __declspec (dllexport) int __cdecl GetSphereSAandVol (radio double, double * sa, double * vol);
...
__declspec (dllexport) int __cdecl GetSphereSAandVol (doublt radio, double * sa, double * vol)
{
...
}


Para especificar convenciones de llamada estándar, coloque la palabra clave __stdcall en la declaración y definición de la función:
extern "C" int __stdcall GetSphereSAandVol (radio double, double * sa, double * vol);
...
int __stdcall GetSphereSAandVol (radio doublt, double * sa, double * vol)
{
...
}

Cuando se utilizan convenciones de llamada estándar, el nombre de la función se decora en la DLL. Puede evitar esto utilizando. def método de archivo para exportar funciones, en lugar del method__declspec (dllexport) . Por lo tanto, NI recomienda que utilice. def método de archivo para exportar funciones stdcall.


 

Construyendo el DLL

Una vez que escriba el código, declare qué funciones exportar y establezca las convenciones de llamada, estará listo para construir su DLL. Seleccione Compilar » Compilar <su proyecto> para compilar y vincular su DLL. Ahora está listo para usar o depurar su DLL de LabVIEW. El archivo adjunto EasyDLL.zip contiene el espacio de trabajo de Visual C ++ usado para crear esta DLL y un VI de LabVIEW que accede a la DLL.

Próximos Pasos

Attachments