LabVIEW与外部程序间DLL文件的调用
LabwindowsCVI调用外部DLL文件的问题
}
}
这样的目的是:在外部调用的时候,便于调用。
C源文件编写完整后,把相关的*.uir文件添加到工程中,然后编写一个*.h文件,命名为exampledll.h,里面包含一个源文件中的函数申明。定义如下:
externint InitUIForDLL (void);//调用面板的函数
InitUIForDLL ();
return 0;
}
(2)通过一个按键来调用dll,即在一个工程中通过一个按钮来调取dll中的函数,来完成此按扭的功能。
与用c源代码来调用的方式一样,只是此工程已经有*.uir对象面板,在*.uir的面板上添加一个按钮,为按钮生成一个函数,在函数中调用外部dll中的函数。在编译前,要将*.lib和*.dll文件和头文件包含在工程中,并且将dll中的函数用一个*.h头文件包含:
int __stdcall DllEntryPoint (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
这两个函数是DLL动态链接库必须包含的两个函数,函数的具体内容为:
#include <cvirte.h>
int __stdcall DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
#include "CFI.h"
static int panelHandle;
int main (int argc, char *argv[])
{
if (InitCVIRTE (0, argv, 0) == 0)
return -1;/* out of memory */
LabVIEW编程调用DLL时遇见的问题
LabVIEW编程调用DLL时遇见的问题对于使用LabVIEW编程的人来说,都知道LabVIEW功能强大,但也会发现似乎缺少某些功能,而像其他编程语言的DLL、ActiveX组件则能提供。
在使用DLL(动态链接库)时,最大的困难就是把函数参数的数据类型映射为相应的LabVIEW中的数据类型。
LabVIEW 提示:未定义符号可能会造成函数和参数无法被识别。
如要解决该问题,检查头文件并确定是否必须添加预定义符号。
单击上一步按钮返回至向导的前一页并添加预定义符号(例如,"NIAPI_stdcall = __stdcall"或"NIAPIDefined = 1")在一次进行串口调试软件的编写过程中,要求使用动态链接库(其实使用VISA同样可以实现),使用导入共享库工具以自动生成配置CLN(Call Library Function)节点,工具在“工具—导入—共享库(.dll)”菜单项下,专门用于将DLL 中函数包装成VI。
下一步下一步点击解析头文件后,依然遇见(如下图)extern UINT Recv(UCHAR *pRecvBytes,UINT unRecvLength);(函数原型)未定义符号可能会造成函数和参数无法被识别。
如要解决该问题,检查头文件并确定是否必须添加预定义符号。
单击上一步按钮返回至向导的前一页并添加预定义符号(例如,"NIAPI_stdcall = __stdcall"或"NIAPIDefined = 1")归咎原因就是头文件中的一些类型定义不符合标准C语法,而使解析器无法获得正确的的mPWIN32_COMMAND定义。
DLL函数的头文件中可能使用了某个系统定义的数据类型,数据类型的定义在windows.h中,(windows.h是Windows SDK的一个文件,VC等开发环境中常常带有Windows SDK),要正确解析必须得到这些数据类型,也就是找到windows.h 这个头文件,用户须把windows.h文件的全路径加在“包括路径”中。
关于LabVIEW产生的DLL被C调用的问题
关于LabVIEW产生的DLL被C调用的问题1 LabVIEW的工作1.1 工程项目从LV8.0开始,想要生成exe、安装程序或DLL就必须首先创建1个工程,然后把所有有关的VI全部添加到工程中,如图1:图1 LV项目为了使目录结构清晰,最好把最后需要输出的VI放置在一起,把子VI放置在一起,如图1中,虚拟目录Top Level Vis用来存放3个输出的VI(可以把它想像成DLL中的函数)、虚拟目录Dynamic Vis存放子VI、虚拟目录Support Files存放支持文件(位图、光标等)。
1.2 VI设置如同在LV中一样,有些VI完全是作为计算模块使用的(调用时不会弹出界面,如图1中的acquire.vi、analyze.vi),而有些是用来显示界面的(调用时弹出对话框,如图1中的present.vi)。
那么如何设置1个输出VI是否显示界面呢?想要产生界面调用的函数,请配置Window Appearance(如图2),然后确保红线圈住的地方必须被选中:图2 VI界面设置1.3 输出配置(Build Specification)右击Build Specification选择New->DLL,弹出DLL输出配置对话框,其有以下对话框需要配置:1.3.1 基本信息(Information)图3∙Build specification name—指定唯一的生成模板名称(出现在项目管理页面中),用以和其他模板相区别∙Target filename—指定输出的DLL名称∙Destination directory—指定生成文件的输出路径∙Build specification description—描述该生成模板的相关信息。
1.3.2 输出源指定(Source Files)图4∙Project Files窗口—显示项目窗口My Computer下列举的项目(如图1),使用图4中的左/右箭头可将My Computer下列举的项目移入/移出Exported VIs和Always Included窗口。
图解LABVIEW调用DLL
前言:LABVIEW是一个强大的图形编程语言,使用很简单,就是你没有任何编程经验也可以LABVIEW编程,对于需要快速上手图形编程的人是一个不错的选择。
在很多时候我们会用C语言写一些计算机的底层驱动,比如USB数据传输或者串口数据传输,如何把我们自己写的驱动程序集成到LABVIEW中呢?下面我就用图和简单说明的方式给大家说说,由于我也是初学,所以有的地方可能会有错误或不准确的地方,欢迎大家指正,废话不多说了,下面开始正式的教程。
目的:通过一个现成的I2C适配器控制I2C接口的AM2311温湿度传感器,将测得的温度和湿度用LABVIEW显示出来,最终效果如图所示。
准备:1、安装LABVIEW2010。
2、I2C适配器1台。
3、I2C适配器上位机驱动函数库,和函数库头文件。
4、AM2311传感器模块一台。
第一步:打开LABVIEW2010,按下图导入我们需要使用的DLL文件。
得到如下界面,点击下一步。
打开DLL和头文件,点击下一步。
到这里我们的库就基本上导入完毕,但是还有一件事情要做,因为在Ginkgo_Driver.dll里面用到了vt214x.dll里面的一些函数,所以要把这个文件拷贝到刚刚生成库的目录下,否则在运行程序的时候会出现找不到这个DLL的错误提示,而且程序也不能正常工作。
我生成的库目录是:D:\Program Files (x86)\National Instruments\LabVIEW 2010\user.lib\Ginkgo_Driver。
你可以根据自己的实际情况处理,拷贝这个文件后在这个目录下的文件如下图所示:到这里库基本上就导入完毕,下面我们就可以在VI程序里面使用这些库函数了。
第二步:打开LABVIEW软件,新建一个VI文件,另存名字为AM2311.vi。
我们在前面板设计为如下界面。
切换到程序款图界面,因为我们程序需要顺序执行,最后需要在一个循环里面循环读取数据,所以我们可以通过平铺顺序结构来设计程序,在平铺顺序结构的第一帧调用刚刚导入的VTIF_I2C_SelectDevice()函数选择设备,在第二帧调用VTIF_I2C_Init()初始化函数初始化I2C适配器,然后就可以循环的读取数据了,最好将数据解析出来并显示出来。
LabVIEW 调用 C-C++ Dll 详解
LabVIEW 调用C/C++ Dll 详解LabVIEW 在配上NI 的采集卡或者别的第三方的硬件,约等于神器(虽然有时候贵了点)。
这样你可以比较集中精力的专注于数据处理了,就不用学习麻烦的Win32 的GUI 编程, 也不用关注和你自己搞的采集板之间的通信了。
对于每一个测控行业的程序来说,基本上都是:初始化-->数据采集-->数据处理-->数据显示-->数据保存-->结束的一个过程。
当然如果是实时的,那么采集,处理,显示就是在一个loop 里面。
当然为了保证实时性,数据处理和数据采集不一定在一个线程里,因为处理的时候把采集给block 住也挺傻的。
LabVIEW 很容易帮你搞定:初始化-->数据采集-->数据处理-->数据显示-->数据保存-->结束但是数据处理部分,是和你的学科紧密相关的,有时候算法会诡异到你很难用VI来实现,那么你就要有C++”target=“_blank”>C++code来搞了。
那么C/C++ 是如何与LabVIEW 交互的呢,本文来较详细的阐述一下,因为准备采用总分总的写作手法...所以先来个概括...1. 把C/C++ code 编译成Dll。
2. 用LabVIEW 的call library node 来调用。
难点在于:如何把LabVIEW 的数据类型和C/C++ 的来对应。
控件x 相当与一个double,当然其类型也是可以选择的(如右图所示)。
boolean 按理说应该是一个bool, 但是传入call library node 的时候,一般要转成unsigned int 型。
cluster 其实就是个struct ,左图的cluster 是:struct tCluster{ double x11; // 类型都可以向右图那样自己配置double x2; int x3;};对于string,这里要着重讲一下,labview 的string 类型里面是包含长度信息的,它不是一个简单的char *它是个LStrHandle 类型:定义咋extcode.h 里面(可以在labview 目录下搜到)typedef struct {int32 cnt;uChar str[1];} LStr, *LStrPtr, **LStrHandle;cnt 就是含有多少个字符,str 这个指针所指的就是数据区的第一个字符。
LABVIEW的DLL与API调用
LABVIEW的DLL与API调用LABVIEW的DLL与API调用一.实验目的1.熟悉LabVIEW调用动态链接库的过程2.学会编写用LabVIEW调用WINDOWS的API函数二.实验器材1.计算机(带有声卡)2.LABVIEW8.20软件三.实验原理在开发自动测量系统时,经常遇到计算机与仪器的通信问题,涉及仪器控制及数据处理问题,LabVIEW语言在这一领域的应用有着独到的优势。
为了在LabVIEW中能够充分利用其他编程语言的优势,LabVIEW提供了外部程序接口能力,包括动态链接库(DLL)、C语言接口(CIN)、ActiveX和Matlab等。
动态链接库是基于Windows程序设计的一个非常重要的组成部分。
LabVIEW 开发中使用DLL,可以使代码更简洁,内存资源的使用更经济,而且可以便捷地利用仪器厂商或第三方提供的仪器控制子程序加速开发进程。
而windows平台包含有大量的API函数,这些API函数提供了大量在Windows环境下可操作的功能,它们位于Windows系统目录下的多个DLL文件中,因此在LabView中调用API 函数和DLL的方法是一致的。
在LabVIEW中,利用库函数节点可以较容易地实现对DLL的调用,从而提高了程序的开发效率。
使用调用库函数节点,可以调用Windows标准的动态连接库,也可以调用用户自己编制的DLL。
LabView中动态链接库的调用可在程序框图的函数选板中选取“调用库函数节点”来完成,该节点位于:互连接口->库和可执行程序->调用库函数节点。
将选择好的调用库函数节点图标放在程序框图中,然后通过对它的节点图标进行配置,可以指定DLL模块中与LabVIEW数据交换的相应的驱动函数。
在调用DLL时,首先要找到找到头文件(*.h)或者函数原型声明,确定你需要调用的函数,注意函数的参数是否包含了原始数据类型参数比如int,char, double,等等或者是否包含了复杂数据类型比如clusters。
labview调用dll方法+
0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
unsigned char i;
unsigned char RH = 0xff;
unsigned char RL = 0xff;
unsigned char *buf=(unsigned char *)pbuf;
do
{
i = *buf ^ RL;
buf ++;
RL = RH ^ CRC_TABLE_H[i];
RH = CRC_TABLE_L[i];
}while(--len);
return(RH * 256 + RL);
}
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
};
/*******************************************************************************
LabVIEW与外部程序间DLL文件的调用
图20 Parameters页面点击“OK”,将生成的CLN的输入段连接到DAQmx Read.vi,return type 输出连接到波形图表上,即可实现采集值放大10倍的功能。
图21 完成后的程序方法二LabVIEW中还有一种方法可以调用DLL文件,在VI的选项栏,依次选择Tools——Import——Shared Library(.dll),弹出Import Shared Library 对话框。
图22 生成Import Shared Library对话框选择Create VIs for a shared library,点击Next,在Shared Library (.dll) Files中输入Scale.dll文件的路径,Head(.h) File里填写头文件的路径。
图23 选择DLL文件路径和头文件路径点击Next,如果DLL文件中依赖其他的一些DLL文件,需要在Include Paths中填写这些文件的路径。
其他选项可以根据客户需求设置,一般默认即可。
这样一直点击Next到最后,选择Open the generated library,点击Finish。
这样可以生成一个.lvlib格式的库文件,里面包含了Scale.vi,这是将调用该DLL 文件的方法封装好的VI,只留下输入和输出接口,方便运用到LabVIEW的程序中。
直接将Scale.vi拖放到刚才的连续采集中即可完成方法一的功能。
图24 完成的程序VC调用LabVIEW生成的DLL文件刚才介绍了LabVIEW调用DLL文件的方法,使用VC调用LabVIEW生成的DLL 文件也很简单。
还是以之前生成Scale 的DLL文件为例,不同的是采集电压程序使用的是C语言的例程,但和LavVIEW实现的功能相同。
首先将先前生成Scale DLL文件时,路径下所有的文件全部复制粘帖到C语言例程的文件夹下。
打开连续采集程序,点击状态栏的Project——Settings,在Project Settings对话框中加载入Scale.lib的静态链接库。
VC调用labview生成的DLL
VC调用LabVIEW生成的DLL文件刚才介绍了LabVIEW调用DLL文件的方法,使用VC调用LabVIEW生成的DLL 文件也很简单。
还是以之前生成Scale 的DLL文件为例,不同的是采集电压程序使用的是C语言的例程,但和LavVIEW实现的功能相同。
首先将先前生成Scale DLL文件时,路径下所有的文件全部复制粘帖到C语言例程的文件夹下。
打开连续采集程序,点击状态栏的Project——Settings,在Project Settings对话框中加载入Scale.lib的静态链接库。
在程序中键入#include "Scale.h",以便引入该DLL函数。
下面是C程序的代码,功能是有限点采集电压,通过Scale.dll文件实现采样值放大10倍的功能。
加粗部分是因为调用DLL文件所做的改动。
#include <stdio.h>#include "NIDAQmx.h"#include "Scale.h"#define DAQmxErrChk(functionCall)if( DAQmxFailed(error=(functionCall)) ) goto Error; elseint main(void){int32 error=0;TaskHandle taskHandle=0;int32 read;float64 data[1000];char errBuff[2048]={'\0'};int i=0;double x10=0;/*********************************************/// DAQmx Configure Code/*********************************************/DAQmxErrChk (DAQmxCreateTask("",&taskHandle));DAQmxErrChk(DAQmxCreateAIVoltageChan(taskHandle,"Dev1/ai0"/*Config correct device*/,"",DAQmx_Val_Cfg_Default,-10.0,10.0,DAQmx_Val_Volts,NULL));/ /DAQmxErrChk(DAQmxCfgSampClkTiming(taskHandle,"",10000.0,DAQmx_Val_Rising,DAQmx_V al_FiniteSamps,1000));/*********************************************/// DAQmx Start Code/*********************************************/DAQmxErrChk (DAQmxStartTask(taskHandle));/*********************************************/// DAQmx Read Code/*********************************************/DAQmxErrChk(DAQmxReadAnalogF64(taskHandle,1000,10.0,DAQmx_Val_GroupByChannel,dat a,1000,&read,NULL));printf("Acquired %d points\n",read);for(i=0;i<1000;i++){Scale(data[i], &x10);printf("the %d Value is : %f \n",i,x10);}Error:if( DAQmxFailed(error) )DAQmxGetExtendedErrorInfo(errBuff,2048);if( taskHandle!=0 ) {/*********************************************/// DAQmx Stop Code/*********************************************/DAQmxStopTask(taskHandle);DAQmxClearTask(taskHandle);}if( DAQmxFailed(error) )printf("DAQmx Error: %s\n",errBuff);printf("End of program, press Enter key to quit\n");getchar();return 0;}所以,使用LabVIEW不仅可以方便地调用各种编译软件生成的DLL文件,自己也能生成DLL文件供其他编译软件调用。
Labwindows调用外部DLL文件的问题
1. dll文件的编写(1)打开软件Labwindows/CVI,点击File->New->project新建一个工程*.prj,如图所示。
然后保存为example.prj。
(2)用同样的方式,新建一个*.c文件,然后按照下图所示,在Edit->Insert Construct->Dllmain,然后软件会自动在c文件中添加以下两个函数:int __stdcall DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)int __stdcall DllEntryPoint (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)这两个函数是DLL动态链接库必须包含的两个函数,函数的具体内容为:#includeint __stdcall DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved){switch (fdwReason){case DLL_PROCESS_ATTACH:if (InitCVIRTE (hinstDLL, 0, 0) == 0)return 0;/* out of memory */break;case DLL_PROCESS_DETACH:CloseCVIRTE ();break;}return 1;}int __stdcall DllEntryPoint (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved){/* Included for compatibility with Borland */return DllMain (hinstDLL, fdwReason, lpvReserved);}然后在上面C源文件中编写相关的函数,然后保存文件为example.c。
Labview调用dll详解(C语言DLL
Labview调用dll详解(C语言DLLLabview调用dll详解(C语言DLL)之一labview中提供了两个C接口,一个是CLF,一个是CIN。
本帖子讨论DLL的调用,也就是CLF。
由于C的强大功能,本帖子讨论C创建的DLL的调用。
首先简单解释一下DLL,也就是动态链接库。
DLL 的好处是屏蔽底层的细节,用户不用也不能打开DLL,便于资源代码数据共享,节省内存等。
一般情况下labview是不需要调用DLL的。
DLL分两类,一类是API,一类是自己创建的DLL。
这两者本质都一样,但是调用一般来说是有区别的。
R) {$ f0 x7 @3 B 要调用DLL必须要有DLL,也就是所谓的路径。
这个一般不会出错的,不用解释了。
其次是选择函数,这个也不难。
线程一般选择UI线程,任意线程的DLL和UI线程DLL有颜色上的区别,其次在源代码中也有区别(这个不是DLL调用失败的主因,不用过多纠缠)。
接下来是调用设置:Ccall和standcall。
一般来说,windows API采用的是standcall,自己创建的采用Ccall。
两种调用区别在于参数进入栈的顺序不同。
这里随便说一下,栈由系统自动分配内存,类似C语言的int a都是分配的栈内存;new分配的是堆内存。
栈内存由系统负责回收,堆内存一般程序员负责释放,所以要注意系统的内存泄漏。
labview的初始化数组也会分配内存,所以不宜频繁调用。
8 h. p8 V/ m, J- D4 X 接下来是最重要的参数配置,也是最复杂的参数配置。
首先要知道函数原型,C语言里面叫导出函数类。
一般在include文件下面的头文件里面。
下面是一个典型的函数原型:extern "C" ZLDS10X_DLL_API SENSOR_HANDLE ZLDS10X_DLL_stdcall ZLDS10X_Open(char * portnum , int baud , int timeout , int address); 值得注意的是,很多人会把函数原型看错。
LabVIEW调用外部EXE
LabVIEW 如何调用外部的script 和可执行程序(2012-12-21 10:35:39)标签:it分类:LabVIEWOverview:如果想在LabVIEW中调用C/C++的dll的话,用Call library node。
但如果你之前的程序是用python,perl或者bat脚本写的,或者干脆就是个可执行的exe程序,那么用System Exec.vi, 它在后面板的位置是Connectivity/Libraries & executables。
Topic1: 使用LabVIEW调用python,perl或者bat的script1. 首先,当然你要在你的机器上安装python,perl,然后把例如c:\Python27之类的路径加到你的environment variable的path里。
2. 设置正确的参数,working directory是你script的路径。
wait until completion?如果是True,则如果你的script会运行1个小时的话,这个VI就会被block住,如果是False,那么script被调用后,VI会立刻返回。
command line就是实际运行的命令了,比如是python ***.py3. 举个栗子比如你在VI的同级目录下写了个test.pyINI Code12 3 4 5 import timedef add(p1, p2): print p1+p2 return p1+p26 7 8 9if __name__=='__main__':time.sleep(5)add(1,2)那么在VI 里面就这样来画,当wait until completion ?=True 时,VI 会被block 住Topic2:使用LabVIEW 调用外部可执行文件exe 和bat 文件如果你运行的exe 已经在环境变量里了,那么OK ,在command line 的输入你可以直接写notepad 等等等。
VC与labview单步联调dll文件
VC生成dll文件给labview调用,有时需要单步调试dll文件看看是否有问题,这个时候需要VC和labview一起联调。
联调之前设置好调试环境:第一步:在Debug的调试选项中设置命令中设置labview程序的地址:E:\Program Files (x86)\National Instruments\LabVIEW 2013\LabVIEW.exe;命令参数为PaoLab.lvprog\main.vi(所要调试程序的主函数);工作目录:..。
第二步:在Debug的链接器选项中设置输出文件和附加库目录;第三步:打开Labview,运行PaoLab中的main.vi(一定要先运行);第四步:执行visual studio 的dll工程的Debug,且设置断点;现在就可以单步执行;附上:dll工程的调试技巧1、调试dll的概述由于dll本身是不可执行的,所以给开发和调试工作带来了一定得难度,在VC++中如何调试dll程序呢?提供了两种解决办法2、调试dll的技巧打开应用程序的工程,选择【Project】—>【Settings】菜单命令,在弹出对话框的“Debug”标签下,“Category”选择“General”,在“Program Arguments”中指定应用程序命令行参数。
“Category”选择“Additional dlls”,输入调试的dll文件,如果使用远程调试,要给出完整的网络路径。
这个dll必须编译成Debug版本的程序,包含有调试信息。
这样尽管dll源不是这个工程的组成部分,也可以在应用程序和dll的源程序中设置断点。
同时使用应用程序的工程来调用dll在同一个工程区内打开dll和应用程序,这样就要求把dll程序的工程添加到应用程序的工作区中。
为了能够调试dll程序,两个工程都是用相同版本的Debug。
在【Project】—>【Settings】对话框的“Link”标签下选中“Generate debug info”。
Labview调用DLL时接口类型匹配简介
调用DLL时接口类型匹配简介1、数值类型Data type:选择数值的类型。
Pass:选择采用传值方式还是传引用方式。
2、布尔类型a. 方法一:使用数值类型作为输入输出。
在连接输入的时候将布尔值转换为数值。
在输出的时候使用判断是否等于0来获取布尔值。
b. 方法二:类型中选择“Adapt to Type”(匹配至类型),数据格式选择“Handles by Value”。
在程序中,直接接入布尔数据,接线端会自动变为布尔类型。
3、字符串类型由于需要为字符串分配内存空间,对于字符串输出,需要为其在输入的一端接入初始字符串。
当初始字符串长度不够时,程序会因为内存内存越界而出错。
4、一维数值数组a. 当生成dll的时候采用“Array Data Pointer”时,参数中会自动增加一个“len”的数值参数:在“Length Input”中会默认设置为此参数值,用以表示数组的长度。
在调用此dll时,对于数组类型,在“Array format”中设置为Array Data Pointer。
同时需要将数组的长度值接至len端上:b. 当生成dll的时候采用“Array Handle Pointer”时,这时输入输出对应的是指向句柄的指针,可执行系统级的操作。
程序可以自动获取数组的长度,所以将不会有“len”参数出现。
在调用此dll时,在“Array format”中选择Array Handle Pointer即可。
在程序中不再需要为数组指定长度。
5、二维数值数组当参数为二维数值数组的时候,在LabVIEW下生成dll时类型只能选择为指向句柄的指针。
调用的方法与4.b类似,只需将“Dimensions”设置为2即可:6、不包含数组的簇数据类型设置为“Adapt to Type”,数据格式设置为“Handles by Value”。
将簇直接接入即可。
7、包含数组的簇、调用方法与调用一维数组类似。
a. 当参数类型为句柄时(一般情况下这种dll是不能使用LabVIEW生成的),在调用dll 的时候,类型设置与不含数组的簇一样:由于需要为这种簇分配内存空间,所以需要将簇的输出接入对应的数据:b. 当参数类型为指向句柄的指针时,将数据格式设置为“Pointers to Handles”。
如何使用LabVIEW调用C#编写的DLL
如何使用LabVIEW调用C#编写的DLL如何使用LabVIEW调用c#编写的DLL最近在做一个项目时,需要在Labview中列出可用的磁盘驱动器,我们可以使用互连接口》库与可执行程序》执行系统命令vi,但是在程序运行时会弹出命令提示符窗口,对于计算机菜鸟用户而言,他们或许会以为那是在执行病毒程序,为了增加用户的好感度,本文采用调用DLL的方式来解决问题。
在调用DLL之前,我们先来创建一个DLL,打开VS2008,新建一个类库项目,如下图:点击确定后进入代码编写窗口。
编写好的代码如下图所示:选择VS2008的生成》配置管理器,打开配置管理器,如下图所示:在活动解决方案配置下拉框中选择Release,然后点击关闭。
选择生成》生成DrivesInfoDll,然后生成一个DLL文件。
在项目的的bin\Release目录下面可以找到生成的DLL文件,如下图所示:我们把它复制我要使用它的地方,如下图:现在,打开LabVIEW2012,新建一个VI,切换到程序框图,选择下图的构造器节点到程序框图:此时将自动打开选择.NET构造器:点击浏览按钮,选择要调用的DLL:点击确定后在对象中选择Class1:,如下图所示:点击确定按钮关闭对话框。
选择下图的调用节点到程序框图:将构造器节点的“新引用”输出端与调用节点的“引用”输入端连接起来,然后在调用节点的“方法”上点击,选择我们要使用的方法,这里选择GetDrivesInfo()。
选择下图的关闭引用到程序框图并连接调用节点的“引用输出”输出端到关闭引用的“引用”输入端。
然后创建一个字符串数组,显示GetDrivesInfo方法的执行结果。
完整的程序框图如下:运行后的前面板结果如下:这说明程序是执行成功了的。
labview调用动态库Dll
利用LabView调用动态链接库.dll
2013.10蜗牛首先确定要实现的功能:
例如:实现c=a+b;动态库的功能是完成加法运算;
第一部分:生成dll库文件的工程;
1)利用vs2010或者VC++编译器建立一个可以生产动态库的工程,在文件》》新建》》项目,选择Visual C++下面的Win32的控制台运用程序;输入工程名和路劲;如图所示会在VC++的文件夹下建立一个test的文件夹;点击确定》》下一步;选择DLL;如下图所示
点击确定后;自动增加的函数文件如下图左边所示;蓝色阴影部分为自己增加的函数功能;
DLL内申明并定义函数的分为两种:第一种为DLL导出函数,第二种为DLL 为内部函数;其中DLL导出函数可以被其他函数调用,DLL函数只能被内部函数调用,应用程序无法调用他们。
所以在DLL中函数add之前有个关键字_declspec(dllexport)来限制,表示函数为dll导出函数。
然后在生成里面点击生成和编译;那么在所建的工程路劲的Debug文件夹下生产一个test.dll的文件;记住这个路劲;
第二部分:编写LabView程序
导出调用LabView调用动态库节点;放置到程序框图版;
双击程序框图中的图标,按如下所示设置,将路劲和函数名写好;在参数设置栏中根据我们在vc中设置的参数类型选择好,点击ok就行;
根据我们定义的a、b类型为int,编辑好界面后,运行程序,调用DLL完成。
如何从LabVIEW中调用动态链接库DLL
问题:如何从LabVIEW中调用动态链接库DLL解答:要从LabVIEW中调用动态链接库(DLL),你需要首先确定是哪种类型的DLL。
基本上有两种类型的DLL需要考虑:C/C++ DLL 和Microsoft .NET assembly. C/C++ DLL 用C, C++, 或其他编程语言生成(除了.NET 语言) 比如Java, Fortran, 或Visual Basic 6.0. .NET DLL 也被称为".NET assembly" 或者就是"assembly". 这个术语的区别在于.NET DLL 与其他DLL的工作方式不同. .NET DLL使用Common Language Runtime (CLR) 和.NET Framework "处理" DLL中的函数.如果DLL是C/C++ DLL:1找到头文件(*.h) 或者函数原型声明.2确定你需要调用的function(s) . 注意函数的参数是否包含了原始数据类型参数比如int, char, double, 等等或者是否包含了复杂数据类型比如clusters.3如果函数没有包含复杂数据类型并且你有头文件(*.h), LabVIEW中一个很好的工具可以帮你简单地导入DLL (并且会帮助你创建DLL的整个库). 你可以在Tools?Import?Shared Library (.dll)...中找到该工具; 按照向导进行下去.4如何函数不含有复杂数据类型但是没有头文件(*.h), 首先确定你使用的是C/C++ DLL因为大部分的编程环境将对这种DLL 生成头文件. 如果你确实在处理C/C++ DLL, 找到该函数的相关文档,因为你需要确定那些在DLL中被调用的函数的参数. 一旦参数被确定,使用Call Library Function Node LabVIEW中的函数手动调用该函数。
【LabVIEW】构造器节点调用C#动态链接库dll
【LabVIEW】构造器节点调⽤C#动态链接库dll
⼀、调⽤C#动态链接库dll
(1)新建VI,后⾯板选择“互连接⼝->.NET->构造器节点”。
(2)双击“构造器节点”图标,找到我们刚刚编译好的dll⽂件,选中相应类名,确定。
(3)选择“互连接⼝->.NET->调⽤节点”。
(4)将⼆者相连,点击调⽤节点选择相应⽅法。
⼆、实现遍历DataTable
互连接⼝-->.net-->构造器节点
在C#中写⼀个函数来实现这个功能,然后再将⼯程⽣成⼀个动态链接库,然后在LabVIEW中就可以调⽤⽣成的dll中所写的这个函数来实现对datatable的读取。
三、常见问题
1、调⽤.net构造器占⽤内存
运⾏不久后提⽰构造器节点内存已满。
问题是在构造了多个引⽤后没有合理的关闭引⽤导致了使⽤引⽤的增加也就导致了内存的增加。
解决⽅法:在使⽤调⽤节点和属性节点时要做到每⼀个节点后都有⼀个对应的关闭引⽤,这样就可以避免由于没有关闭引⽤⽽使内存增加的问题。
注意:如果有for循环,要在循环外关闭引⽤,否则也会产⽣错误的。
2、.NET构造器节点该类不包括任何公共构造器
1、确认已经在类和⽅法上加了Public关键字;
2、把构造函数删掉。
3、报错“Object reference not set to an instance of an object”
某函数调⽤产⽣这个问题。
该部函数传⼊参数有ref,数据类型是数组,删掉这个传⼊参数就不报错了,但其他函数同样传⼊参数⼜不报错...个例先记录下来,原因待查。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
LabVIEW与外部程序间DLL文件的调用什么是DLL文件DLL(动态链接库)文件是Dynamic Link Library的缩写形式,是一种允许程序共享执行特殊任务所必需的代码和其他资源的可执行文件。
其多数情况下是带有DLL扩展名的文件,但也可能是EXE或其他扩展名。
Windows提供的DLL文件中包含了允许基于Windows 的程序在Windows环境下操作的许多函数和资源。
动态链接提供了一种方法,使进程可以调用不属于其可执行代码的函数。
这些函数的可执行代码位于一个DLL中,该DLL包含一个或多个已被编译、链接并与使用它们的进程分开存储的函数。
DLL还有助于共享数据和资源,多个应用程序可同时访问内存中单DLL副本的内容。
总之,DLL是一个包含可由多个程序同时使用的代码和数据的库。
动态链接是相对于静态链接而言的。
所谓静态链接是指把要调用的函数或者过程链接到可执行文件中,成为可执行文件的一部分。
换句话说,函数和过程的代码就在程序的exe文件中,该文件包含了运行时所需的全部代码。
当多个程序都调用相同函数时,内存中就会存在这个函数的多个拷贝,这样就浪费了宝贵的内存资源。
而动态链接所调用的函数代码并没有被拷贝到应用程序的可执行文件中去,而是仅仅在其中加入了所调用函数的描述信息(往往是一些重定位信息)。
仅当应用程序被装入内存开始运行时,在Windows的管理下,才在应用程序与相应的DLL之间建立链接关系。
当要执行所调用DLL中的函数时,根据链接产生的重定位信息,Windows才转去执行DLL中相应的函数代码。
由于向运行于Windows操作系统下的程序提供代码、数据或函数,程序可根据DLL文件中的指令打开、启用、查询、禁用和关闭驱动程序。
在Windows操作系统中,DLL对于程序执行是非常重要的, 因为程序在执行的时候, 必须链接到DLL文件, 才能够正确地运行。
而有些DLL文件可以被许多程序共用,因此程序设计人员可以利用DLL文件, 使程序不至于太过巨大。
但是当安装的程序越来越多,DLL文件也就会越来越多, 如果当删除程序的时候, 没有用的DLL文件没有被删除的话, 久而久之就造成系统的负担了。
通过使用DLL,程序可以实现模块化,由相对独立的组件组成。
因为模块是彼此独立的,所以程序的加载速度更快,而且模块只在相应的功能被请求时才加载。
此外,可以更为容易地将更新应用于各个模块,而不会影响该程序的其他部分。
例如,可能有一个工资计算程序,税率每年都会更改,当这些更改被隔离到DLL中以后,我们无需重新生成或安装整个程序就可以应用更新。
总的来说,使用DLL文件有以下好处:1、多个应用程序可以共享代码和数据。
比如Office软件的各个组成部分有相似的外观和功能,这就是通过共享动态链接库实现的。
2、在钩子程序过滤系统消息时必须使用动态链接库。
3、动态链接库以一种自然的方式将一个大的应用程序划分为几个小的模块,有利于小组内部成员的分工与合作,而且各个模块可以独立升级。
如果小组中的一个成员开发了一组实用例程,他就可以把这些例程放在一个动态链接库中,供其他成员使用。
4、实现应用程序的国际化,往往需要使用动态链接库。
使用动态链接库可以将针对某一国家、语言的信息存放在其中。
例如,在使用AppWizard生成应用程序时,我们可以指定资源文件使用的语言,这就是通过提供不同的动态链接库实现的。
对于不同的版本,使用不同的动态链接库,常用的一些编程软件均可以编写DLL文件。
DLL 不是独立运行的程序,而是某个程序的一个部分,它只能由所属的程序调用,用户不能,也不需要打开它。
LabVIEW调用DLL文件LabVIEW支持通过调用DLL文件的方式与其它编程语言混合使用。
比如,在实际的工程项目中,用户可以用C++语言实现软件的运算部分,并把这些功能构建在DLL文件中,然后再使用LabVIEW编写程序的界面部分,并通过调用编写好的DLL来调用运算部分的功能。
LabVIEW 中是通过Call Library Function Node(CLN)节点来完成DLL文件调用的。
创建一个新的VI,右击程序框图,在Functions Palette中依次选中Connectivity——Libraries&Executables工具栏即可找到该节点(图1)。
图1 Call Library Function Node将节点放置在程序框图中,双击会出现它的配置对话框,共有四页。
第一页用于填写被调用函数的信息(图2)。
Library name or path需给出DLL文件名和路径,操作系统路径下的DLL文件,直接输入文件名也可调用,否则必须输入全路径。
在这里已经给出名字的DLL 是被静态加载到程序中的,也就是说当调用了这个DLL的VI被装入内存时,DLL同时被装入内存。
LabVIEW也可动态加载DLL,只要勾选上Specify path on diagram的选项即可。
选择了这个选项,在Library name or path中输入的内容就无效了,取而代之的是CLN 节点多出一对输入输出,用于指明所需要使用的DLL的路径。
这样,当VI被打开时,DLL 不会被装入内存,只用程序运行到需要使用这个DLL中的函数时,才把其装入内存。
Function name是需要调用的函数的名称,LabVIEW会把DLL中所有的暴露出来的函数都列出,用户只要在下拉框中选取即可。
Thread栏用于设定哪个线程里运行被调用的函数。
用户可以通过CLN 节点的配置面板来指定被调用函数运行所在的线程。
CLN 的线程选项非常简单,只有两项:Run in UI thread和Run in any thread。
LabVIEW的程序框图上直接可以看出一个CLN节点是选用图2 填写被调用函数信息的什么线程。
如果Run in UI thread,节点颜色是橙色的;Run in any thread则是浅黄色的(图3)。
图3 CLN不同线程对比通常情况下,除非使用的动态链接库是多线程安全的,CLN 中选择Run in any thread 方式;否则必须选择Run in UI thread方式。
判断一个动态链接库是不是多线程安全的,需通过以下方法:如果一个动态链接库的文档中没有明确说明它是多线程安全的,那么就要当作是非多线程安全的;在可以看到动态链接库源代码的条件下,如果代码中存在全局变量、静态变量或者代码中看不到有lock一类的操作,那么这个动态链接库也就肯定不是多线程安全的。
选择了Run in any thread方式,LabVIEW会在最方便的线程内运行动态链接库函数,且一般会与调用它的VI在同一个线程内运行。
因为LabVIEW是自动多线程的语言,它也很可能会把动态链接库函数分配给一个单独的线程运行。
如果程序中存在没有直接或间接先后关系的两个CLN节点,LabVIEW很可能会同时在不同的线程内运行它们所调用的函数,也许是同一函数。
对于非多线程安全的动态链接库,这是很危险的操作。
很容易引起数据混乱,甚至是程序崩溃。
选择Run in UI thread方式,因为LabVIEW只有一个界面线程,所以如果所有的CLN 设置都是界面线程,那么就可以保证这些CLN调用的函数肯定全部都运行在同一线程下,肯定不会被同时调用。
对于非多线程安全的动态链接库,这种方式就保证了它的安全。
让我们回到配置对话框第一页,Calling convention用于指明被调用函数的调用约定。
这里只支持两种约定:stdcall和C call。
它们之间的区别在于,stdcall由被调用者负责清理堆栈,C call由调用者清理堆栈。
这个设置错误时,可能会引起LabVIEW崩溃,也就是说如果LabVIEW调用DLL函数时出现异常,首先应该考虑这个设置是否正确。
(Windows API 一般使用的都是stdcall;标准C的库函数大多使用C call。
如果函数声明中有类似__stdcall 这样的关键字,它就是stdcall的。
)第二页是函数参数的配置(图4)。
图4 配置函数的参数DLL和LabVIEW之间传递参数,最常用的三种数据类型是数值、数值型数组和字符串。
C语言中经常把指针或者数据的地址在函数间传递,在32位操作系统中,可以使用int32数值来表示指针。
因此,当需要在LabVIEW中传递指针数据时,可以使用I32或U32数值类型来表示这个地址类型的数据。
但是,64位的程序中,数据的地址只能使用I64或U64来表示。
这样,如果一个调用了DLL函数的VI,并且函数参数中有地址型数据,使用固定数据类型的数值来表示地址,就要准备两份代码。
解决方法是使用LabVIEW中的新的数据类型Pointer-sized Integer。
这个数据类型的长度在不同的平台上会自动使用32位或64位长度。
如果在C语言函数参数声明中有const关键字,可以选中Constant选项。
布尔类型在DLL函数和LabVIEW VI之间传递没有专有的数据类型,是利用数值类型来传递的。
输入时先把布尔值转变为数值,在传递给DLL函数;输出时再把数值转为布尔值。
对于数组的传递,LabVIEW只支持C数据类型中的数值型数组,传递数组类型需要注意的的是“Array Format”要选择“Array Data Pointer”。
这个设置中还有其他两个选项,带有“Handle”的参数类型都是表示LabVIEW定义的特殊类型的。
在第三方的DLL中不会使用到数组参数作为输出值时,要记得为输出的数组数开辟空间。
开辟数据空间的方法有两种:第一种方法,创建一个长度满足要求的数组,作为初始值传递给参数,输出数的数据就会被放置在输入数组的所在的内存空间内。
第二种方法是直接在参数配置面板上进行设置。
在Minimum size中写入一个固定的数值,LabVIEW就会按此大小为输出的数组开辟空间。
在Minimum size 中选择函数的其它数值参数,而不是固定数值。
这样LabVIEW会按照当时被选择的参数值的大小来开辟空间。
字符串与使用与数组是非常类似的,实际上在C语言中字符串就是一个I8数组。
在NI软件的安装路径下打开当前使用版本的LabVIEW文件夹,通过examples\dll\data passing\Call NativeCode.llb找到简单数据类型在LabVIEW与C之间的对应关系。
部分常见关系见表1。
表1 数据类型对比第三页用于为DLL设置一些回调函数,可以使用这些回调函数在特定的情形下完成初始化、清理资源等工作(图5)。
图5 设置回调函数如果为Reserve选择了一个回调函数,那么当一个新的线程开始调用这个DLL时,这个回调函数首先被调用。