Una descripción general del acceso a DLL o bibliotecas compartidas desde LabVIEW

Actualizado el Aug 7, 2023

Las bibliotecas de vínculos dinámicos (DLL) proporcionan una forma para que los programas accedan al código externo. El concepto de Windows de una DLL también se encuentra en los sistemas Macintosh y UNIX, pero generalmente se denomina biblioteca compartida o archivo de objeto compartido.

Las DLL son secciones de código que están vinculadas al programa principal en tiempo de ejecución (vinculadas dinámicamente). Esto tiene varias ventajas. El primero es el espacio. Si muchas aplicaciones comparten un determinado algoritmo, puede compilarlo una vez como DLL y luego usar el mismo código en todas las aplicaciones. Las DLL también proporcionan una forma de distribuir el código de una manera que permite fácilmente que los programas de nivel superior accedan al código. Un buen ejemplo de esto son los controladores de hardware, en los que la interfaz entre el software de la aplicación y el hardware suele ser a través de una DLL.

LabVIEW puede acceder a las funciones contenidas en las DLL a través del Call Library Function Node.

Recopilar la información necesaria

Para llamar a una función desde una DLL, necesita conocer cuatro datos:

  1. El archivo de biblioteca en el que reside el código de la función
  2. El nombre de la función tal como aparece en la biblioteca.
  3. El número y tipo de argumentos que requiere la función, incluido el tipo de retorno.
  4. La convención de llamadas

Los elementos dos y tres juntos forman el function prototype.

Si es el autor de la biblioteca, ya debería tener esta información. Si la biblioteca es de un tercero, debe consultar la documentación que vino con la biblioteca para recopilar esta información. (Si está intentando acceder a una función que forma parte del SDK de Win32, consulte el enlace a continuación). Es posible que necesite buscar en el archivo de encabezado (.h) incluido con la DLL para encontrar el prototipo de la función. . LabVIEW puede llamar a funciones con convenciones C o estándar (PASCAL, WINAPI). La mayoría de los archivos DLL utilizan convenciones de llamada estándar, y esto normalmente se puede suponer, si no se indica explícitamente. Si las convenciones de llamada son incorrectas, LabVIEW fallará cuando su VI intente llamar a la función.

Cuando tenga la información, debería verse así:

Biblioteca:
Prototipo de función:

Convenciones de llamadas:
mydll.dll
void MyFunction (int a, double * b, char * string, unsigned long arrayize, short * dataarray);
standard

Desafortunadamente, para llamar con éxito a esta función, debe comprender lo que espera la función. El primer problema es que los tipos de datos enteros no son necesariamente consistentes en tamaño de una plataforma a otra. LabVIEW alivia este problema al referirse a todos los números enteros de manera consistente. Para convertir de la notación de LabVIEW a la notación de su plataforma particular, use la siguiente tabla:
LabVIEWWin32Win16Macintosh (PowerPC)La mayoría de los sistemas UNIX
int8signed charsigned charsigned charsigned char
int16shortint, shortshortshort
int32int, longlongint, longint, long
uInt8charcharcharchar
uInt16unsigned shortunsigned int, unsigned shortunsigned shortunsigned short
uInt32unsigned int, unsigned longunsigned longunsigned int, unsigned longunsigned int, unsigned long


Además, también necesita saber qué espera la función en términos de punteros. Algunos parámetros se pasan por valor y otros por puntero. Para los que se pasan como punteros, la función puede esperar un solo valor, o puede esperar la ubicación inicial de una matriz de valores. Saber cuál es fundamental si desea llamar con éxito a la función de biblioteca. En el ejemplo anterior, puede adivinar a partir de los nombres de los parámetros y leer en el manual (hipotético) que la matriz de datos debe ser un puntero a un array de cortos, mientras que b es un puntero a un valor doble.

La última información es que las cadenas generalmente se pasan a las DLL como cadenas C. La cadena AC es un array de caracteres y, como tal, normalmente se ve en los prototipos de funciones como "char *", un puntero a un array de caracteres. Por cierto, las funciones C saben cuándo han llegado al final de una cadena porque siempre terminan con un carácter nulo (valor ASCII 0x00).

Con toda esta información, puede escribir un prototipo de función ligeramente revisado (asumiendo un sistema operativo Win32):

void MyFunction (int32 a, double * b, char * string, uInt32 arraysize, int16 * dataarray);

Donde:
b es un puntero a un valor doble,
cadena es un puntero de cadena C, y
dataarray es un puntero a un array de int16s

Configuración del nodo de función de biblioteca de llamadas

Una vez que haya reunido toda la información necesaria, estará listo para configurar el nodo de función de biblioteca de llamadas. Lo primero que debe hacer, por supuesto, es colocar un nodo en el diagrama de bloques. El Call Library Function Node se encuentra en Functions Palette >> Advanced >> Call Library Function. Después de colocar el nodo en el diagrama, debe configurarlo. Haga clic en el nodo y seleccione "Configure..."


Esto abrirá un cuadro de diálogo que le permite configurar la llamada a la función.

En este diálogo, ingrese la ruta a la biblioteca deseada, el nombre de la función y las convenciones de llamada. Finalmente, configure el prototipo de la función usando el parámetro del diálogo. Especifique el tipo de retorno y luego agregue parámetros al prototipo usando los botones "Add a Parameter Before" o "Add a Parameter After". Utilice los cuadros desplegables " "Data Type," y "Pass" para especificar el tipo de datos adecuado y cómo se pasa el parámetro.

Una vez terminado, el nodo mostrará el tipo de datos de terminal apropiado en el diagrama de bloques:

Si no se puede encontrar el archivo de la biblioteca, o la función no se puede encontrar dentro de la biblioteca, obtendrá una flecha de ejecución rota. Haga clic en la flecha de ejecución rota para mostrar la lista de errores y encontrar el nodo infractor.


Declarar una llamada de función a una función de biblioteca segura para subprocesos (reentrante)

Si sabe que la función que está llamando en la biblioteca es segura para subprocesos, puede informar a LabVIEW configurando adecuadamente el nodo. Si el nodo no está configurado como una llamada segura para subprocesos, se supone que la llamada no es segura para subprocesos y se ejecuta en el subproceso de la interfaz de usuario. Esto asegura que no se realicen dos llamadas simultáneamente a una función que no sea segura para subprocesos. Sin embargo, si la función es segura para subprocesos, debe configurarse como tal, ya que esto conduce a mejoras de rendimiento.

Para configurar una función de biblioteca de llamadas como segura para subprocesos, cambie el cuadro desplegable que dice "Run in UI Thread" a "Reentrant.

Una vez hecho esto, la parte superior del nodo cambia de naranja a amarillo, lo que indica que la llamada es reentrante.

---->