1C#中如何调用动态链接库DLL

1C#中如何调用动态链接库DLL
1C#中如何调用动态链接库DLL

C#中如何调用动态链接库DLL(转)

每种编程语言调用DLL的方法都不尽相同,在此只对用C#调用DLL 的方法进行介绍。首先,您需要了解什么是托管,什么是非托管。一般可以认为:非托管代码主要是基于win32平台开发的DLL,activeX的组件,托管代码是基于.net平台开发的。如果您想深入了解托管与非托管的关系与区别,及它们的运行机制,请您自行查找资料,本文件在此不作讨论。

(一)调用DLL中的非托管函数一般方法

首先,应该在C#语言源程序中声明外部方法,其基本形式是:

[DLLImport(“DLL文件”)]

修饰符extern返回变量类型方法名称(参数列表)

其中:

DLL文件:包含定义外部方法的库文件。

修饰符:访问修饰符,除了abstract以外在声明方法时可以使用的修饰符。

返回变量类型:在DLL文件中你需调用方法的返回变量类型。

方法名称:在DLL文件中你需调用方法的名称。

参数列表:在DLL文件中你需调用方法的列表。

注意:需要在程序声明中使用System.Runtime.InteropServices命名空间。

DllImport只能放置在方法声明上。

DLL文件必须位于程序当前目录或系统定义的查询路径中(即:系统环境变量中Path所设置的路径)。

返回变量类型、方法名称、参数列表一定要与DLL文件中的定义相一致。

若要使用其它函数名,可以使用EntryPoint属性设置,如:

[DllImport("user32.dll",EntryPoint="MessageBoxA")]

static extern int MsgBox(int hWnd,string msg,string caption,int type);

其它可选的DllImportAttribute属性:

CharSet指示用在入口点中的字符集,如:CharSet=CharSet.Ansi;

SetLastError指示方法是否保留Win32"上一错误",如:SetLastError=true;

ExactSpelling指示EntryPoint是否必须与指示的入口点的拼写完全匹配,如:ExactSpelling=false;

PreserveSig指示方法的签名应当被保留还是被转换,如:PreserveSig=true;

CallingConvention指示入口点的调用约定,如:

CallingConvention=CallingConvention.Winapi;

此外,关于“数据封送处理”及“封送数字和逻辑标量”请参阅其它一些文章[2]。

C#例子:

1.启动https://www.360docs.net/doc/b09561919.html,,新建一个项目,项目名称为“Tzb”,模板为“Windows应用程序”。

2.在“工具箱”的“Windows窗体”项中双击“Button”项,向“Form1”窗体中添加一个按钮。

3.改变按钮的属性:Name为“B1”,Text为“用DllImport

调用DLL弹出提示框”,并将按钮B1调整到适当大小,移到适当位置。

4.在类视图中双击“Form1”,打开“Form1.cs”代码视图,在“namespace Tzb”上面输入“using System.Runtime.InteropServices;”,以导入该命名空间。

5.在“Form1.cs〔设计〕”视图中双击按钮B1,在“B1_Click”方法上面使用关键字static和extern声明方法“MsgBox”,将DllImport 属性附加到该方法,这里我们要使用的是“user32.dll”中的“MessageBoxA”函数,具体代码如下:

[DllImport("user32.dll",EntryPoint="MessageBoxA")]

static extern int MsgBox(int hWnd,string msg,string caption,int type);

然后在“B1_Click”方法体内添加如下代码,以调用方法“MsgBox”:MsgBox(0,"这就是用DllImport调用DLL弹出的提示框哦!","挑战杯",0x30);

6.按“F5”运行该程序,并点击按钮B1,便弹出如下提示框:

(二)动态装载、调用DLL中的非托管函数

在上面已经说明了如何用DllImport调用DLL中的非托管函数,但是这个是全局的函数,假若DLL中的非托管函数有一个静态变量S,每次调用这个函数的时候,静态变量S就自动加1。结果,当需要重新计数时,就不能得出想要的结果。下面将用例子说明:

1.DLL的创建

1)启动Visual C++6.0;

2)新建一个“Win32Dynamic-Link Library”工程,工程名称为“Count”;

3)在“Dll kind”选择界面中选择“A simple dll project”;

4)打开Count.cpp,添加如下代码:

//导出函数,使用“_stdcall”标准调用

extern"C"_declspec(dllexport)int_stdcall count(int init);

int_stdcall count(int init)

{//count函数,使用参数init初始化静态的整形变量S,并使S自加1后返回该值

static int S=init;

S++;

return S;

}

5)按“F7”进行编译,得到Count.dll(在工程目录下的Debug 文件夹中)。

2.用DllImport调用DLL中的count函数

1)打开项目“Tzb”,向“Form1”窗体中添加一个按钮。

2)改变按钮的属性:Name为“B2”,Text为“用DllImport 调用DLL中count函数”,并将按钮B1调整到适当大小,移到适当位置。

3)打开“Form1.cs”代码视图,使用关键字static和extern 声明方法“count”,并使其具有来自Count.dll的导出函数count的实现,代码如下:

[DllImport("Count.dll")]

static extern int count(int init);

4)在“Form1.cs〔设计〕”视图中双击按钮B2,在“B2_Click”方法体内添加如下代码:

MessageBox.Show("用DllImport调用DLL中的count函数,n传入的实参为0,得到的结果是:"+count(0).ToString(),"挑战杯");

MessageBox.Show("用DllImport调用DLL中的count函数,n传入的实参为10,得到的结果是:"+count(10).ToString()+"n结果可不是想要的11哦!!!","挑战杯");

MessageBox.Show("所得结果表明:n用DllImport调用DLL中的非托管n 函数是全局的、静态的函数!!!","挑战杯");

5)把Count.dll复制到项目“Tzb”的binDebug文件夹中,按“F5”运行该程序,并点击按钮B2,便弹出如下三个提示框:

第1个提示框显示的是调用“count(0)”的结果,第2个提示框显示的是调用“count(10)”的结果,由所得结果可以证明“用DllImport调用DLL中的非托管函数是全局的、静态的函数”。所以,有时候并不能达到我们目的,因此我们需要使用下面所介绍的方法:C#动态调用DLL中的函数。

3.C#动态调用DLL中的函数

因为C#中使用DllImport是不能像动态load/unload assembly那样,所以只能借助API函数了。在kernel32.dll中,与动态库调用有关的函数包括[3]:

①LoadLibrary(或MFC的AfxLoadLibrary),装载动态库。

②GetProcAddress,获取要引入的函数,将符号名或标识号转换为DLL内部地址。

③FreeLibrary(或MFC的AfxFreeLibrary),释放动态链接库。

它们的原型分别是:

HMODULE LoadLibrary(LPCTSTR lpFileName);

FARPROC GetProcAddress(HMODULE hModule,LPCWSTR lpProcName);

BOOL FreeLibrary(HMODULE hModule);

现在,我们可以用IntPtr hModule=LoadLibrary(“Count.dll”);来获得Dll 的句柄,用IntPtr farProc=GetProcAddress(hModule,”_count@4”);来获得函数的入口地址。

但是,知道函数的入口地址后,怎样调用这个函数呢?因为在C#中是没有函数指针的,没有像C++那样的函数指针调用方式来调用函数,所以我们得借助其它方法。经过研究,发现我们可以通过结合使用System.Reflection.Emit及System.Reflection.Assembly里的类和函数达到我们的目的。为了以后使用方便及实现代码的复用,我们可以编写一个类。

1)dld类的编写:

1.打开项目“Tzb”,打开类视图,右击“Tzb”,选择“添加”-->“类”,类名设置为“dld”,即dynamic loading dll的每个单词的开头字母。

2.添加所需的命名空间及声明参数传递方式枚举:

using System.Runtime.InteropServices;//用DllImport需用此命名空间

using System.Reflection;//使用Assembly类需用此命名空间

using System.Reflection.Emit;//使用ILGenerator需用此命名空间

在“public class dld”上面添加如下代码声明参数传递方式枚举:

///

///参数传递方式枚举,ByValue表示值传递,ByRef表示址传递

///

public enum ModePass

{

ByValue=0x0001,

ByRef=0x0002

}

3.声明LoadLibrary、GetProcAddress、FreeLibrary及私有变量hModule和farProc:

///

///原型是:HMODULE LoadLibrary(LPCTSTR lpFileName);

///

///DLL文件名

///函数库模块的句柄

[DllImport("kernel32.dll")]

static extern IntPtr LoadLibrary(string lpFileName);

///

///原型是:FARPROC GetProcAddress(HMODULE hModule,LPCWSTR lpProcName);

///

///包含需调用函数的函数库模块的句柄

///调用函数的名称

///函数指针

[DllImport("kernel32.dll")]

static extern IntPtr GetProcAddress(IntPtr hModule,string lpProcName);

///

///原型是:BOOL FreeLibrary(HMODULE hModule);

///

///需释放的函数库模块的句柄

///是否已释放指定的Dll

[DllImport("kernel32",EntryPoint="FreeLibrary",SetLastError=true)]

static extern bool FreeLibrary(IntPtr hModule);

///

///Loadlibrary返回的函数库模块的句柄

///

private IntPtr hModule=IntPtr.Zero;

///

///GetProcAddress返回的函数指针

///

private IntPtr farProc=IntPtr.Zero;

4.添加LoadDll方法,并为了调用时方便,重载了这个方法:///

///装载Dll

///

///DLL文件名

public void LoadDll(string lpFileName)

{

hModule=LoadLibrary(lpFileName);

if(hModule==IntPtr.Zero)

throw(new Exception("没有找到:"+lpFileName+"."));

}

若已有已装载Dll的句柄,可以使用LoadDll方法的第二个版本:

public void LoadDll(IntPtr HMODULE)

{

if(HMODULE==IntPtr.Zero)

throw(new Exception("所传入的函数库模块的句柄HMODULE为空."));

hModule=HMODULE;

}

5.添加LoadFun方法,并为了调用时方便,也重载了这个方法,方法的具体代码及注释如下:

///

///获得函数指针

///

///调用函数的名称

public void LoadFun(string lpProcName)

{//若函数库模块的句柄为空,则抛出异常

if(hModule==IntPtr.Zero)

throw(new Exception("函数库模块的句柄为空,请确保已进行LoadDll操作!"));

//取得函数指针

farProc=GetProcAddress(hModule,lpProcName);

//若函数指针,则抛出异常

if(farProc==IntPtr.Zero)

throw(new Exception("没有找到:"+lpProcName+"这个函数的入口点"));

}

///

///获得函数指针

///

///包含需调用函数的DLL文件名

///调用函数的名称

public void LoadFun(string lpFileName,string lpProcName)

{//取得函数库模块的句柄

hModule=LoadLibrary(lpFileName);

//若函数库模块的句柄为空,则抛出异常

if(hModule==IntPtr.Zero)

throw(new Exception("没有找到:"+lpFileName+"."));

//取得函数指针

farProc=GetProcAddress(hModule,lpProcName);

//若函数指针,则抛出异常

if(farProc==IntPtr.Zero)

throw(new Exception("没有找到:"+lpProcName+"这个函数的入口点"));

}

6.添加UnLoadDll及Invoke方法,Invoke方法也进行了重载:///

///卸载Dll

///

public void UnLoadDll()

{

FreeLibrary(hModule);

hModule=IntPtr.Zero;

farProc=IntPtr.Zero;

}

LabVIEW调用动态链接库dll

/DE9,(:) W ??GOO &/1 ??- &/1 &DOO /LEUDU\ )XQFWLRQ 1RGH ?? ? ?? ?? ) - ) ? ) ? /LEUDU\ QDPH RU SDWK '// <+? "+? '// ??? γ I+? -/ '// ?? ?? ?) -- '// 9, ??p '//? ??p /DE9,(: ? W ??'// 1 6SHFLI\ SDWK RQ GLDJUDP - ? - - -- - /LEUDU QDPH RU SDWK ??? ?v? - # ) &/1 ?? ??? ǎ ? ? '// +? - ?9, ? '// ??p ?- ? ? - '//? ?1J ??p )XQFWLRQ QDPH c ) /DE9,(: 1'//?? . ′ ? ?- γ 7KUHDG ǎ?t ? /- ) ? J? ) ?# /DE9,(: ?? ? W -?? ? &DOOLQJ FRQYHQWLRQ ǎ ) ) ?t -/ ?t VWGFDOO < & FDOO ? ) Z ǎ VWGFDOO ) #** & FDOO ) # - ?? ) $ ? /DE9,(: ? ? t ? ? ) 8 /DE9,(: ) '// ? G? # - ?? ? :LQGRZV $3, ?? . VWGFDOO O& ? ? & FDOO 8 ? ń?BBVWGFDOO - ? p ?? VWGFDOO

?? ? ?? - . ? )? ? ǎ('//?? . ) ? -. ) ?t ?? ? ??? ? 8 (5HVHUYH - - ) ?)? ? ) - '// - ) G ) - ( ? ? ? ?> ? 8 ? ? -- '// ? " ? b) 8QUHVHUYH ? t ) $ERUW ? t 9, ? " ) 8 $ERUW ? 9,?? # ? - ? -/ ) ? '// # ??t ?? ? ? ? 3URWRW\SH IRU WKHVH SURFHGXUHV ? ? 8 ?? '// ( /DE9,(: ?? ? - )

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。如果函数没有包含复杂数据类型并且你有头文件(*.h),该DLL在数据类型的定义上与LabView一致,那么LabVIEW中一个很好的工具可以帮你简单地导入DLL(并且会帮助你创建DLL的整个库)。你可以在工具—>导入—>共享库(.dll)...中找到该工具,按照向导进行下去。 如果函数不含有复杂数据类型但是没有头文件(*.h),或者由于DLL编写不够规范,在数据类型的定义上与LabView并不完全一致,你需要确定那些在DLL 中被调用的函数的参数,一旦参数被确定,使调用库函数节点中的函数手动调用该函数。这是你需要对调用的函数进行手工配置。 在调用DLL库中函数时,必须知道以下信息:函数返回的数据类型、函数调用的方式、函数的参数及类型、DLL库文件的位置等。右键单击调用库函数图标,在弹出的菜单选项中选择配置...选项,可得到下图所示的配置对话框。

LabVIEW与外部程序间DLL文件的调用

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时遇见的问题

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文件的全路径加在“包括路径”中。例如Visual C++6.0编译环境中头文件位于安装目录下VC98文件夹下的Include文件中。 而“预处理定义”中,当用户需要写一些宏定义,那么就写在这个位置。 在网络上看到在预处理定义中添加了如下代码 ULONG = unsigned long; VOID = void; LONG = long; UCHAR = unsigned char; PUCHAR = unsigned char*; PULONG = unsigned long*; WINAPI; BOOL = bool; USHORT = unsigned short; PUSHORT = unsigned short*; 点击下一步也不会遇到上述问题,导入工具会帮助你解析出全部导出函数并自动生成VI。

基于调用DLL的LabVIEW数据采集的实现

万方数据

陋的论文得到两院院士关注l 数采与监测 卡,此卡为12/16位A/D转换分辨率,最高采样频率町达lOOK 3.3基于调用DLL的应用实例 Hz。PCI--911 1数据采集卡自带了Windows下的驱动程序库 本例子通过调用凌华数据采集卡的PCI—Dask.dll实现简单PCI—Dask.d11.库内包含了数据采集用的所有函数,下面就将要的单通道的旋转机械转子不平衡时振动速度信号的监测,主要调用的有关甬数作个简要的说明。 目的在于说明在LabVIEW中调用DLL的具体应用。在速度传在说明函数之前,有必要对DLL中的数据类型作个介绍。感器检测的信号输入数据采集卡之前,经过了凋理模块,实行116表示有符号16位整型,对应C语言中的。holt;U16表示无了放大、隔离和滤波等,最后显示的波形接近转子不平衡时振符号16位整型,对应c语言中的unsignedshort;1"64表示双精动的正弦波形。 度浮点数,对应c语言中的double。 程序设计采用顺序结构,设置i个调用动态链接库节点。 116Regkter Card(U16CanIType.U16card ):该函数的 第一帧调用ese函 数进行数据采集卡的初始化,输入_numRgitr_Card 功能是初始化数据采集卡,使其做好输入输出操作的准备,返数据采集卡的型号和卡号;第:二帧调用AI—VreadChannel函数回值为数据采集卡的卡号,此卡号数为数据采集卡插在PCI插 读取通道的电压,并用波形图表显示I叶J来;第i帧调用Re一槽中的序列号,在下文例子中为0。CardType和card_num为函lea.se_Card函数释放数据采集卡所占资源,程序结束。具体各个数的参数,CardType为数据采集卡的型号,凌华公司对不同的节点的配置依照上文介绍的步骤设置好即可。程序的前面板如型号有对应的代码,在下文例子中,其代码为2l。在调用其它函图2所示,程序框图如图3所示。 数之前,必须先调用此函数。 116Release Card(U16card):该函数用来释放由 一_humReg ister_Card函数分配的存储参数值以关闭装载的数据采集卡。在程序的最后要调用此函数。 116 AI—VreadChannel(U16CardNumber,U16Channel,U16 AdRange.F64*voltagel:该函数的功能读取指定通道的电压值。参数Channel为指定的通道数,AdRange为输f“的电压的显示范围,也有相应的代码,vohage为输l叶』的电压值。 3.2在LabVIEW中调用DLL的步骤 下面具体的介绍在LabVlEW‘中调用DLL的步骤和应用。软件为LabVIEW8.2中文版。 首先从程序框图中的函数面板中依次选择:互联接 口一库与呵执行程序一调用库函数节点,即可调出调用库 函数节点图标。右键单击,在弹出的菜单中选择“配置…”,弹出调用库函数对话框(图1所示)。这时就町根据需要,对其中的各项进行设置, 图1调用库函数的设置对话框 “库名或路径”选项为要载入的被调用的DLL文件,本文例子中调用的是PCI—Dask.du。“函数名”选项为要调用的函数名称,线程一般默认即町。“调用规范”选项选择对库函数的调用规则,在此选择stdcall。在调用自己用C语言编写的程序而后编译成动态链接库的DLL文件时,“调用规范”选c。 接下来是对“参数”选项的设置,选择网l中的参数项。根据调用的函数,在此项设置下添加和设置相应的参数,参数名称、类型和数据类型都要与被调用函数中的参数名相同。 设置好这两项后.调用库函数节点的配置就完成了,接下来就是外部的编程和连线了。 旋转机械振动监测 图2程序的前面板 图3程序的程序框图 当数据获取后,要进一步对数据进行各种分析处理,就可 在此基础上进行了。 PCI—Dask.dU中提供了丰富的函数,对于模拟量的输入除了调用上文介绍的函数进行数据采集外。同样可以调用其它的相关函数来实现同样的功能,如可调用AI—ReadChannel,AI_ContReadChannel.M_Volts(:ale等。 4结束语 在LabVIEW中通过调用动态链接库来驱动数据采集卡,能使LIl'VIEW和普通的数据采集卡结合进行数据采集.扩大了LabVIEW的应用范罔。节约开发R寸问,同时可以充分利用LabVlEW图形化编程的方便快捷和强大的虚拟仪器开发功能,来实现高效、低成本的应用开发。 (下转第250页) @啪罔邮局订阅号:82娟360元/-q-一79—   万方数据

关于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窗口。 ?Exported Vis窗口—指定DLL的输出函数(VI),至少要指定1个输出VI。选定移入的VI,Define VI Prototype按钮可使用,并且在点击后弹出如图5所示对话框: 图5 接口原型定义对话框

如何从LabVIEW调用动态链接库DLL

如何从LabVIEW调用动态链接库DLL 主要软件: 主要软件版本:1.0 主要软件修正版本:N/A 次要软件:N/A 问题:如何从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的整个库). 你可以在T ools?Import?Shared Library (.dll)...中找到该工具; 按照向导进行下去. 4如何函数不含有复杂数据类型但是没有头文件(*.h), 首先确定你使用的是C/C++ DLL因为大部分的编程环境将对这种DLL生成头文件. 如果你确实在处理C/C++ DLL, 找到该函数的相关文档,因为你需要确定那些在DLL中被调用的函数的参数. 一旦参数被确定,使用Call Library Function Node LabVIEW中的函数手动调用该函数。 5如果你需要调用的函数含有复杂的数据类型,你需要手动使用LabVIEW中的Call Library Function Node功能直接调用, 在配置对话框中添加原型. 注意如果你的复杂数据类型是结构体而不是原始数据类型(int, double, char), 从基于C的编程语言中创建wrapper DLL. 因为C/C++ 结构并不总是与LabVIEW的数据类型相对应的, wrapper DLL 能够近似的解析复杂结构的内容并且把它们翻译成原始类型. 比如,如果在C中的一个结构体包含char * (字符串或者字符数组), 可以创建一个wrapper function,LabVIEW将直接用char * type 调用它, 把它放在结构体中然后按照顺序调用DLL. 注意如果你有DLL源代码,可以直接修改DLL使得它能够接收一个char * 而不是该结构体. 如果DLL是.NET assembly: 6为了在LabVIEW中使用.NET assembly , 简单地使用.NET 面板(Connectivity?.NET) 找出所有可用的函数. 7首先使用结构节点来例示.NET assembly中的一个类. 8通过简单地连接结构节点的类引用到属性节点或者调用节点,使用属性节点和调用节点来获取该类的属性和方法

引用 LabVIEW中调用VC++生成的DLL文件

引用LabVIEW中调用VC++生成的DLL文件 labview 2010-07-03 01:32:26 阅读146 评论0 字号:大中小订阅 引用 Senple Chan的LabVIEW中调用VC++生成的DLL文件 1.// 新建一个空的Win32 Dll 工程,加入新的cpp,写入下面代码 _declspec(dllexport) int sum(int a, int b) { return a+b; } //Build出一个dll:sum.dll 2.// 新建一个新的Win32 Console程序 //选择Simple Console Application,修改main函数所在的cpp #include "stdafx.h" #include using namespace std; // for base type and LoadLibrary #include // define function pointer which will point to sum(a, b) typedef int(*Func)(int,int); int main(int argc, char* argv[]) { HMODULE dll = ::LoadLibrary("sum.dll"); // 加载刚才那个dll,路经要对if(dll) { Func f = (Func)GetProcAddress(dll, ?sum@@YAHHH@Z); // 加载那个sum函数 if(f) cout<

Labview调用C语言、Matlab脚本节点以及库函数节点的方法

Labview调用C语言、Matlab脚本节点以及 库函数节点的方法 Labview调用C语言的方法 CIN(Code InterfaceNode)节点是LabVIEW中用来调用C/C++代码的功能节点。它与动态链接库的不同之处在于,它能够将代码集成在VI中作为单独的一个VI发布,而不需要多余的文件。另外,它提供了函数入口,它可以根据用户提供的输入输出自动生成函数入口代码,从而使用户专心关注代码功能而不用为函数声明、定义等语句费心。因此CIN节点与DLL在不同的场合有不同的优势,但是CIN节点的使用比调用DLL要复杂得多。 由于LabVIEW中数据的存储格式遵循了C语言中数据的存储格式,并且二者完全相同,所以用户可以向CIN传递任意复合的数据结构。另外,CIN比图形化语言可获得更高的执行效率。 注意:对于完全相同的代码,CIN和DLL的执行效率是完全一样的。 如果要使用CIN节点,你必须安装了C编译器。在Windows下,CIN支持以下编译器: Microsoft Visual C++ Symantec C CIN节点必须调用.lsb文件。.lsb文件是通过外部编译器与CINTools工具结合将C代码编译生成的。 下面我们通过一个Step byStep的实例来看如何在LabVIEW中实现CIN节点调用,本例所用外部编译器为MicrosoftVisual C++6.0。 第一步:在程序框图放置一个空CIN节点; CIN节点位于FunctionsPalette的Connectivity->Libraries& Executables->Code InterfaceNode。 第二步:创建CIN节点的输入输出端口;

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 #include "NIDAQmx.h" #include "Scale.h" #define DAQmxErrChk(functionCall) if( DAQmxFailed(error=(functionCall)) ) goto Error; else int 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

LabVIEW如何方便地调用DLL文件

LabVIEW如何方便地调用DLL文件 LabVIEW调用DLL文件 LabVIEW支持通过调用DLL文件的方式与其它编程语言混合使用。比如,在实际的工程项目中,用户可以用C++语言实现软件的运算部分,并把这些功能构建在DLL文件中,然后再使用LabVIEW编写程序的界面部分,并通过调用编写好的DLL来调用运算部分的功能。 LabVIEW 中是通过Call Library Function Node(CLN)节点来完成DLL文件调用的。创建一个新的VI,右击程序框图,在Functions Palette中依次选中Connectivity——Libraries & Executables工具栏即可找到该节点(如下图)。 将节点放置在程序框图中,双击会出现它的配置对话框,共有四页。第一页用于填写被调用函数的信息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节点是选用的什么线程。如果Run in UI thread,节点颜色是橙色的;Run in any thread则是浅黄色的

在LabVIEW中利用DLL实现数据采集

在LabVIEW中利用DLL实现数据采集Realization of Data Acquis ition with DLL in LabVIEW 班级学号:0704114-23 姓名:杨鹏

摘要: 随着计算机技术及虚拟仪器技术的迅速发展, 虚拟仪器正逐渐成为测试领域的发展方向。本文介绍了在LabVIEW 环境下驱动普通数据采集卡的重要方法- - 动态链接库机制(DLL), 并结合具体实例介绍了一种利用LabVIEW 提供的Call LibraryFunction (CLF)节点实现对动态链接库(DLL)调用的关键技术及步骤, 实现LabV IEW 与普通数据采集卡的结合, 丰富LabVIEW 对硬件的控制能力。并将数据库技术应用于虚拟测试系统中, 建立了Access 数据库, 实现数据的存储和自动管理,从而拓展了虚拟测试系统的功能。 关键词:动态链接库(DLL); 数据采集; 1 绪论

目前, 电子测试仪器的发展方向正在从简单功能组合向以个人计算机(PC)为核心的通用虚拟测试平台过渡, 从硬件模块向软件包形式过渡。建立在PC 机和数据采集设备上的虚拟仪器系统, 由于其特有的灵活和强大的功能, 也越来越广泛的应用于实验室研究和工业控制中的测试及测量领域。从简单的仪器控制, 数据采集到尖端的测试和工业自动化, 从大学实验室到工厂, 从探索研究到技术集成, 人们都可以发现LabVIEW 应用的成果和开发的产品。LabVIEW采用基于流程图的图形化编程方式, 也被成为G 语言(graphical language)。 G 语言编程和虚拟仪器技术已经成为工业界和学术界关注的热点技术之一。数据采集是LabVIEW 的核心技术之一, 也是LabVIEW 与其他编程语言相比的优势所在。使用LabVIEW 的DAQ 技术,可以编写出强大的DAQ 应用软件。NI 公司生产的系列数据采集卡借助LabVIEW 内部的DAQ 库的驱动,可以在LabVIEW环境下运行。但由于NI 公司的采集卡价格比较昂贵,但是选择第三方的数据采集卡, 就需要解决LabVIEW 与非NI 数据采集卡的兼容和驱动的问题。 2 LabVIEW 调用外部程序代码的途径之一———动态链接库机制 LabVIEW 具有强大的外部接口能力, 可以实现LabVIEW与外部的应用软件, C 语言, Windows API 以及HiQ 等编程语言之间的通信, 在LabVIEW 中可用的外部接口包括:DDE,CIN,DLL,MATLAB Script 以及HiQ Script 等。合理地使用这些接口,充分利用其他软件的功能, 弥补LabVIEW 自身的不足, 可以编 写出功能更加强大的LabVIEW应用软件。 动态链接库(Dynamic Link Libraries,简称DLL)是一个可执行模块, 但不接受任何消息, 所以并不可以直接运行, 只是提供一群函数供Windows 应用程序或其他的动态链接函数库调用。动态链接库只有在别的模块中调用了它的某个函数以后才发生作用。由于动态链接库在应用程序运行期间被连接起来的,故称为动态链接库。动态链接库(DLL)一直是基于Windows 程序设计的一个非常重要的组成部分。DLL 是一种基于Windows的程序模块, 它可以在运行时刻被装入和连接。为了实现LabVIEW对普通数据采集卡的支持, 用户可以使用LabVIEW 提供的调用库函数节点CLF (Call Library Function)和代码接口节点CIN(Code Interface)将编程灵活的C 语言和直观方便的LabVIEW程序结合起来。但是比较调用库函数节点CLF 和代码接口节点CIN 这两种方法, 使用CLF 节点访问动态链接库DLL 更具优势:首先, DLL 是外部模块, 自行开发一个DLL 比使用CIN 节点易于实现且便于维护。其次, CIN

Labview DLL调用指南-非常有用

【转】labview dll的调用 【转载】武汉高收入高福利公司排行榜 在LabVIEW中调用DLL的整个过程及注意事项 2011-09-15 21:25:44| 分类:驱动开发| 标签:|字号大中小订阅 1. LabVIEW支持的数据类型 < xmlnamespace prefix ="o" ns ="urn:schemas-microsoft-com:office:office" /> 另外,可参考…\Program Files\National Instruments\LabVIEW 2009\examples\dll\data passing\Call Native Code.llb\Call DLL.vi。…此VI列举了LabVIEW与C语言中兼容的数据类型。见下表。

2. 在VI里调用DLL时,在DLL的左侧给输出端口添加初始化的值。 给输出端口添加初始化值的目的是分配内存给输出端口。该初始化数组元素的个数至少为实际输出数组的个数。若过小,则DLL不正常运行;若相等,则DLL正常运行;若过大,则DLL的数组输出端口除有效数据外,还有其他一些为0的非有效数据。 < xmlnamespace prefix ="v" ns ="urn:schemas-microsoft-com:vml" />

3.使用DLL的步骤 1)制作子VI,添加控件接口到连接端(connector)。 2)在新建的VI中添加DLL,在DLL中指定其路径,会自动添加该DLL包含的输入输出端口。对于数值型输出,选择Point to value。 选中“Specify path or diagram”,表示动态调用该DLL,此时路径取决于 最上端的路径输入端,Library name or path里输入的路径无效。 在parameters页,系统会自动添加DLL的输入输出端口,如果添加不完整,则需要再手动添加额外的输入端或者输出端。 需检查DBL输入:Value;DBL输出Pointer to Value。

LabvIEW与usb使用方法

1楼发表于昨天 12:07 |只看该作者|倒序浏览|打印 本帖最后由 wyb4993 于 2011-7-15 09:36 编辑 在前面,我们已经介绍过利用NI的VISA来实现USB HID双向通信。借助VISA来实现USB HID通信,是比较稳定和可靠的,缺点就是需要安装庞大的VISA驱动程序,而且我们的STM32硬件需要被MAX正常识别出来,如果不能识别,那么这种方法是行不通的。 https://www.360docs.net/doc/b09561919.html,/bbs/forum.php?mod=viewthread&tid=27417 其实我们还有另外的方法,就是通过LabVIEW调用DLL文件,实现USB HID的双向通信。 (说明:请不要向我索要LabVIEW源代码,开发千般辛苦,况且是公司的代码,我相信大家的水平都比我高,通过下面的入门介绍,相信大家可以做出来的。) 1、什么是DLL文件? 动态链接库(Dynamic Link Library,缩写为DLL)是一个可以被其它应用程序共享的程序模块,其中封装了一些可以被共享的例程和资源。动态链接库文件的扩展名一般是DLL,它和可执行文件(exe)非常类似,区别在于DLL中虽然包含了可执行代码却不能单独执行,而应由Windows应用程序直接或间接调用。 按照我们的理解,DLL文件中有C语言(也可以是其它语言)写的函数,究竟有多少个函数,由DLL文件的创建者决定的。DLL有助于促进模块式程序的开发。因为它的封装性、***性好。 DLL文件也不一定由开发者创建的,其实windows系统中就提供了大量的DLL文件,例如windows编程所需的大量API函数存储在Kernal.DLL文件中。 LabVIEW不仅可以调用我们自己创建的的DLL文件,也可以调用windows系统中的DLL文件。下面我们分这两种情况进行说明。 2、LabVIEW调用我们创建的DLL文件 LabVIEW的“调用库函数节点”在以下路径: “互连接口”→“库与可执行程序”→“调用库函数节点”

基于调用DLL的LabVIEW数据采集的实现

技术创新 中文核心期刊《微计算机信息》(测控自动化)2008年第24卷第12-1期 360元/年邮局订阅号:82-946 《现场总线技术应用200例》 数采与监测 基于调用DLL 的LabVIEW 数据采集的实现 Realization of Data Acquisition Based on Calling DLL in LabVIEW (南京工业大学)张亿雄 顾海明 ZHANG Yi-xiong GU Hai-ming 摘要:介绍了在LabVIEW 中调用外部程序代码的方法。详细探讨了DLL 文件的调用方法,并通过实例介绍了基于非NI 公司 的数据采集卡的数据采集的实现。 关键词:LabVIEW;数据采集;动态链接库 中图分类号:TP39 文献标识码:B Abstract:Methods of calling external code in LabVIEW are introduced.Detailed procedures of calling the DLL file are discussed.An data acquisition example of using data acquisition card of non-NI company is offered.Key words:LabVIEW;Data acquisition;DLL 文章编号:1008-0570(2008)12-1-0078-02 1引言 随着计算机技术和总线技术的发展,仪器技术领域发生了巨大的变化,尤其是以计算机为核心的设计思想以及仪器系统与计算机软件技术的紧密结合,出现了虚拟仪器这个全新的概念,它实际上是一个按照仪器需求组织的数据采集系统。 美国国家仪器公司(National Instruments,NI)的LabVIEW 是目前最为流行的虚拟仪器的开发环境,与大多数程序软件不 同,LabVIEW 是一个图形化的程序语言, 又称为G 语言。使用这种语言编程时,基本上不要写程序代码,取而代之的是流程图,方便了工程技术人员的程序设计。 数据采集(DAQ )是LabVIEW 的核心。NI 公司对其全部的数据采集产品提供了专门的驱动程序,如最新的NI-DAQmx 8.6。不仅如此,NI-DAQmx 包含了数据采集助手(DAQ Assis -tant )和测量与自动化探测(MAX ),他们可以使任务配置、硬件安装、 编码开发变得更简单更快捷。但在许多情况下,用户基于LabVIEW 开发的虚拟仪器不一定使用NI 公司的数据采集设备,而是使用非NI 的数据采集设备,这样一方面节约了硬件开支,一方面又可以利用LabVIEW 的强大的数据分析能力。在使用非NI 公司的数据采集设备时,在LabVIEW 中编程时就没有用NI 公司的数据采集设备时直接调用相应的VI 节点图标来的方便了。虽然现在有的数据采集卡制造商专门开发了支持LabVIEW 的数据采集VI 节点,如凌华的DAQ-LVIEW PnP , 研华的LabVIEW Drivers ,但是要实现更高级更自主的程序开发,这些VI 节点就难以胜任了,同时对于没有提供 支持LabVIEW 的数据采集VI 节点的数据采集卡, 这时最常用的方法就是调用数据采集卡驱动程序的DLL (Dynamic Link Li -brary)文件。 2LabVIEW 调用外部程序代码的方法 2.1调用C 语言源代码的方式(CIN 方式) 在LabVIEW 中提供了与C 语言接口的代码接口图标CIN (Code Interface Node),CIN 通过输入、 输出端口实现两种语言之间的数据传递,当LabVIEW 的程序运行到CIN 节点时,数据由 CIN 的输入端口传递给C 源代码,程序转去执行C 源代码, 代码执行完后得到的数据结果由CIN 的输出端口返回给Lab -VIEW 。使用这种方法需要有C 语言编程的支持。 2.2调用动态链接库的方式 (CLF 方式)动态链接是相对于静态链接而言的,它是一种应用程序在运行时与库文件链接起来的技术。动态链接库是一个可执行模块,它不可以直接运行,只是提供一群函数供应用程序调用。在这个过程中,动态链接不像静态链接要把调用的函数代码复制到应用程序中而成为其一部分,它调用的函数代码并没被复制到应用程序中,而仅在其中加入调用函数的描述信息,程序执行时才将代码载入内存,当多个程序使用相同的DLL 时,内存中只需装载一次,从而可以避免多个程序调用相同的DLL 时内存资源的浪费。 LabVIEW 在调用DLL 中的函数时要知道函数的参数、 参数类型、函数返回值的类型、DLL 库文件的位置等。 目前大多数的数据采集卡制造商提供了DLL 库函数的驱动程序,以方便在VB 、VC++等环境中数据采集系统程序的编制。同样,在LabVIEW 中可以通过调用库函数(CLF,Call Li - brary Function )节点图标来调用DLL 。在LabVIEW 中调用DLL ,不需要开发者编制数据采集程 序代码,对用C 、VB 的编程能力基本没什么要求, 开发者可以专注于在LabVIEW 中的编程。开发者只需要熟悉DLL 中的各个函数功能以及函数的参数及类型,而数据采集卡附带的说明书都对其有说明,这样对于其它语言编程能力不是很好的开发者就能简单方便的来实现数据采集功能了。因为其简单方便,这种方法也是用LabVIEW 和非NI 公司的数据采集卡结合组建数据采集系统的常用方法。 3基于调用动态链接库的数据采集 应用实例 3.1DLL 中相关函数的介绍 本文涉及的数据采集卡是凌华公司的PCI-9111数据采集 张亿雄:硕士研究生 78--

相关主题
相关文档
最新文档