当前位置:首页 >> 信息与通信 >>

labview-利用 Code Interface Node 将 C 语言创建的代码集成到 LabVIEW 项目中


该文档版权归上海微视泰科工作室所有,转载请注明出处! 网址:http://www.microvt.com Email: hightechyoung@yahoo.com 作者:HighTech Young

6

调用文本编程语言创建的代码

6.1. 概述
本章主要叙述在 LabVIEW 中如何调用利用传统的基

于文本的编程工具创建的代码. 通过学习本章您将了解以下知识: 利用 Code Interface Node 将 C 语言创建的代码集成到 LabVIEW 项目中; 利用 Call Library Function Node 调用动态链接库。 在用 LabVIEW 开发大型的项目的过程中,尽管它能给开发者提供快速的解决方案,但是有时候传统的基 于文本的开发工具在实现某些功能时相对可能容易些(如开发对运行时间要求很苛刻的程序) ,或者有些任务 不能通过调用 LabVIEW 的函数来直接实现(如操作系统 API 的某些功能) 。这个时候就可以考虑使用 Code Interface Node (CIN)或者 Call Library Function Node 来调用基于文本的开发工具开发的代码。通常来说在 大型的项目开发过程中这样做的目的主要有以下几个方面: 代码的复用。对一个项目开发团队来说,整个团队使用的开发工具可能不只是一种。从横向来看,团 队中负责各子系统的开发人员可能使用的开发工具不尽相同,, 从纵向来看,整个团队多年来可能已 经换过多种不同的开发工具。为了能减少重复工作,共享代码或重复利用以前的代码,可以用 CIN 将 C 代码或者用 Call Library Function Node 将其它工具创建的 DLL 集成到 LabVIEW 项目中来。 项目的开发效率。 虽然用 LabVIEW 为项目提供解决方案, 其效率相对于基于文本的传统开发工具大 大提高, 但是有些时候用传统的开发工具实现某些功能却比 LabVIEW 来的容易。 例如开发与底层硬 件交互或者开发对运行时间要求很苛刻的程序时,VC 可能就比 LabVIEW 来得方便。或者开发者需 要某种特殊的算法, 而且这种算法用传统的开发工具实现要比 LabVIEW 开发容易些 (如图像处理的 一些算法等) 。这时开发者就可以用 CIN 或者 Call Library Function Node 把传统开发工具的长处和 LabVIEW 的长处结合在一起,共同为项目提供解决方案。 LabVIEW 不能胜任的工作。LabVIEW 提供了很多函数和开发的 toolkit,但是这并不意味着 LabVIEW 可以完成任何事情。例如操作系统 API 提供的某些功能,LabVIEW 的函数库中就没有提 供。那么开发者就可以用 CIN 或者 Call Library Function Node 来扩展 LabVIEW 为项目提供方案 的能力。 值得注意的是, LabVIEW 项目执行调用的外部代码时, 在 执行的线程将被占用, 直到执行节点返回为止。 也就是说如果线程正在执行外部代码,那么它将不会处理其它任务,当然用户也将不能中断此执行过程。那 么开发人员在将外部代码集成到项目中时,如果代码如果完成的任务执行时间较长,就一定要慎重处理了。

1

该文档版权归上海微视泰科工作室所有,转载请注明出处! 网址:http://www.microvt.com Email: hightechyoung@yahoo.com 作者:HighTech Young

6.2. 用 CIN 调用 C 代码
Code Interface Node (CIN)可以被看作是LabVIEW用来扩展自身开发能力的一种方法, 它通过将VC++ 或Symantec C(在Linux平台上可以是gcc)编写的代码集成到VI中来扩展LabVIEW自身能力的不足。与调用 DLL不同的是,CIN可以将外部的代码与VI集成在一起,一旦编译成功后就可随VI一起分发,不需要原来的源 文件或者其它文件来支持其运行。从运行的效率而言,DLL和CIN相同。 在LabVIEW项目中使用CIN,一般通过以下途径: 1. 指定接口的输入输出参数的类型传递方式; 2. 创建.C代码的框架并完成代码; 3. 编译代码为LabVIEW可以识别的格式(.lsb格式) 4. 加载CIN目标代码 以下章节用实际例子对其逐步详细说明。为了把重点放在CIN调用步骤的说明上,该例子只简单完成两个 数的求和的运算。 6.2.1. 指定接口的输入输出参数的类型和传递方式 首先,在 Function ->Connectivity->Libraries & Executables 中(如图 6-1)选取 Code Interface Node 放在 Diagram 上。默认情况下,CIN 节点只有一个输入端口和一个输出端口,用户可以通过用鼠标拖动图标 的边框,或者通过选择节点端口右键菜单中的 Add Parameters/Remove Parameters 来增加/删除参数。但是 增加的参数是成对出现的。每增加一个输入(或输出)端口,都会有一个与之相对应的输出(或输入)端口出现。

图 6-2 CIN 节点在 LabVIEW8 函数面板中的位置

图 6-3 CIN 的输入输出参数

输入输出参数的数据类型由与之连接的 Control 或 Indicator 决定。也就是说输入参数的类型取决于与其 连接 Control 的数据类型,输出参数的类型取决于与其连接的 Indicator 的类型。 CIN 的参数传递方式可以分为:Input-Output 和 Output Only 两种类型。不同的连接方式表示了不同的参 数传递方式。
2

该文档版权归上海微视泰科工作室所有,转载请注明出处! 网址:http://www.microvt.com Email: hightechyoung@yahoo.com 作者:HighTech Young

默认情况下,LabVIEW 中 CIN 节点的参数传递方式为“Input-Output”(传递指向参数的指针),节点 左边连接输入参数,右边连接输出参数。例如图 6-3 a)中所示,连接一个 32 位整型 Control 作为输入参数, 连接一个 32 位的整型 Indicator 作为输出参数。 VI 调用 CIN 的时候, 在 LabVIEW 只将输入参数的指针传递 给 CIN 目标代码,CIN 代码执行完毕后,LabVIEW 会将输入参数指针指向的值传递给输出 Indicator。在这 种情况下,LabVIEW 认为 CIN 代码可以修改连接到输入端 Control 的值。此时就要注意,如果 VI 中有其它 地方也需要调用 CIN 前输入 Control 中的值作为参数,那么必须在调用 CIN 前 copy 输入 Control 的值,否则 就有可能出错。 在参数传递时,也可以只在输入端连接 Control,而使输出端悬空。例如图 6-3 b)中所示,连接一个 32 位整型 Control 作为输入参数,而输出端悬空。这时 LabVIEW 会认为 CIN 不会修改传递给它参数的值。 如果 VI 中有其它地方也需要调用 CIN 前输入 Control 中的值作为参数, 就不必在调用 CIN 前 copy 输入 Control 的值了。当然必须确保在 CIN 代码中不能修改参数的值,如果用户非要更改参数的值,那么更改后的值将在 输入 Control 中显示。 如果用户只想用一对连接端子连接输出参数,就可以将参数传递方式设置为 Output Only 类型。可以通过 选择端子右键菜单中的 Output Only 将参数传递类型设置为 Output Only 类型。设置成功后端子对应得输入端 就会变成灰色(图 6-3 c) 。对于 Output Only 类型的参数,LabVIEW 会为其分配专门的空间来存放返回值, 然后将指向分配空间的指针传递给 CIN,一旦 CIN 执行完成,就会按照与其连接的 Indicator 数据类型将返回 值显示在出来。 但是在某些情况下, 可能会将同一个输出连接到多个具有不同数据类型的 Indicator 上 (图 6-3 d) ,这时对 LabVIEW 来说就有可能出现判断数据类型错误的情况。为了解决此问题,可以将一个 Control 连接到与输出对应得输入端子上,输出端子将会引用该 Control 的数据类型(图 6-3 d) 。 对于求和运算的例子来说,我们指定两个 8 位的整型量作为输入参数,指定一个 8 位的整型量作为输出 参数,结果如下:

图 6-4 Sum=A+B 的 CIN 参数

6.2.2. 创建.C 文件框架并完成代码 为 CIN 节点指定了输入输出参数后,可以通过选择节点右键菜单中的 Create .c File 生成 CIN 源代码的模 版。用户在生成的模版中添加 CIN 要完成功能的代码。 为求和运算例子创建的源代码如下:
/* CIN source file */ #include "extcode.h" MgErr CINRun(int8 *A, int8 *B, int8 *Sum); MgErr CINRun(int8 *A, int8 *B, int8 *Sum) { /* Insert code here */ return noErr; }

这个文件不仅定义了 CIN 使用 模版会自动包含 LabVIEW 程序目录下 Cintools 目录中的 extcode.h 文件, 的基本数据类型和函数原型, 还定义了可能与系统头文件中定义有冲突的一些常量。 Cintools 目录中还有一个 hosttype.h 文件, 此文件用于解析系统头文件和 extcode.h 之间的差异, 同时也包含了给定平台的通用头文件。 始终在.C 源文件的起始位置包含 extcode.h 文件,如果代码对系统进行了调用,则一般应该在 extcode.h
3

该文档版权归上海微视泰科工作室所有,转载请注明出处! 网址:http://www.microvt.com Email: hightechyoung@yahoo.com 作者:HighTech Young

文件后立刻包含 hosttype.h 文件,然后再将系统的头文件包含进来。对给定的系统来说,hosttype.h 只包含 了部分头文件,如果用户需要的系统头文件没有包含在内,则可以在它之后包含需要的头文件。 在生成的 C 模版文件中, CINRun 必须存在外, 除 还有其它 7 个用于维护现场的函数可选则使用: CINLoad, CINSave, CINUnload, CINAbort, CINInit, CINDispose, and CINProperties。LabVIEW 在运行到 CIN 节点时 会调用调用 CINRun 函数,CINRun 函数会接收到输入输出参数。7 个用于清理现场的函数只有在特定的情况 下才会被调用。例如,LabVIEW 在第一次加载 vi 时会调用 CINLoad 函数,如果用户要在第一次加载 vi 时 完成某种特殊的任务,就可以在 CINLoad 函数中添加相应的代码。下面代码给出了一个在 CINLoad 中添加 代码的模版:
CIN MgErr CINLoad(RsrcFile reserved) { Unused (reserved); /* Insert code here */ return noErr; }

一般说来,在 C 源代码文件中只需要编写 CINRun 函数九可以了,只有在某些特殊情况(如完成某些初 始化,预分配空间或者维护交叉调用的信息)下才调用现场维护的函数。 对于两个数求和的例子来说,我们可以在 CINRun 函数的 /* Insert code here */ 处添加下句 A 和 B 求 和的代码如下:
/* CIN source file */ #include "extcode.h" MgErr CINRun(int8 *A, int8 *B, int8 *Sum); MgErr CINRun(int8 *A, int8 *B, int8 *Sum) { /* Insert code here */

*Sum = *A + *B;
return noErr; }

6.2.3. 编译代码为 LabVIEW 可以识别的.lsb 格式 完成了代码的编写后就需要将代码编译成 LabVIEW 可识别的.lsb 格式。LabVIEW 支持不同平台上的 编译器(Windows 上的 VC++,Symantec C,Linux 的 gcc,以及 Mac 上的 xCode)编译 CIN。开发平台和编 译器不同编译的方法也不同。对于 Linux 和 Mac 平台上 CIN 的编译,用户可以参考 LabVIEW 的操作手册, 这里只对在 Windows 平台上用 VC 来编译 CIN 的方法做详细讨论。 CIN 的编译其实并不复杂,但是 NI 在 LabVIEW 的手册中提供的编译方法(特别是基于 Makefile 的编译 方法)并不是很完美,这使很多同仁几乎为此忙到崩溃(我曾经在论坛中见到好多朋友为此花了大量的时间 来求救) 。下面提供两种在 Win32 平台下使用 VC++6 来的编译的 CIN 的方法:Makefile 方法和 VC++ IDE 方 法。 Makefile 方法 1. 在 C 源文件的目录中创建一个与 C 源文件同名且后缀名为.mak 的文件(如 add.mak)其中包含以下 内容:
name = C 源文件去掉后缀的部分 type = CIN 4

该文档版权归上海微视泰科工作室所有,转载请注明出处! 网址:http://www.microvt.com Email: hightechyoung@yahoo.com 作者:HighTech Young cinlibraries = Kernel32.lib CINTOOLSDIR=Cintools 目录的路径 !include <$(CINTOOLSDIR)\ntlvsb.mak>

例如为两个数求和的例子创建的 add.mak 文件如下:
name = add type = CIN cinlibraries = Kernel32.lib CINTOOLSDIR=d:\cintools !include <$(CINTOOLSDIR)\ntlvsb.mak>

文件中“CINTOOLSDIR=CIN 工具所在目录”是指向 LabVIEW 安装目录中 Cintools 目录的路径。但是 由于编译器不识别长文件名,所以此处的路径比须是 DOS 操作系统的路径名(即目录和文件名 8 字符,后缀名 3 字 符的格式) ,否则编译器将不能识别。建议将整个 Cintools 目录 copy 到一个容易用 DOS 命名方式表达的路径下使 用,如 d:\cintools。

2.

.mak 文件创建完成后,运行 VC++ 6 并选择 File -> Open 打开.mak 文件(注意不要打开工作空间) 。 此时将会跳出询问是否生成新的 project 来包装 makefile 和询问工作平台的对话框(图 6-5 和图 6-6)选择 Yes 和 OK.

图 6-5 包装 makefile 的对话框

3. 保存 Project 并选择 Build 就会生成需要的.lsb 文件

图 6-6 为包装的项目选择平台

VC++ IDE 方法 使用 VC++ IDE 编译.lsb 的方法可以按照下面步骤来完成。 1. 创建新的 DLL Project。选择 File -> New…选择 Win32 Dynamic-Link Library 作为要创建项目的类型, 并为项目命名(图 6-7),选 OK 后再选择 An Empty DLL Project,然后生成一个 dll 项目;
5

该文档版权归上海微视泰科工作室所有,转载请注明出处! 网址:http://www.microvt.com Email: hightechyoung@yahoo.com 作者:HighTech Young

2. 为创建的项目添加所需要的目标文件和库文件。选择 Project -> Add To Project -> Files… 添加 Cintools 目录中的下列 4 个文件①cin.obj, ②labview.lib, ③lvsb.lib 和④lvsbmain.def.到项目中

图 6-7 创建 DLL 项目

3. 将 Cintools 添加到包含路径中。选择 Project -> Settings…把 Settings for 下拉列表框切换到 All Configurations.选择选项卡 C/C++,把 category 下拉列表框切换到 Preprocessor 然后在 Additional Include Directories 域中输入 Cintools 所在的路径。(如图 6-8)

图 6-8 将 Cintools 添加到包含路径 6

该文档版权归上海微视泰科工作室所有,转载请注明出处! 网址:http://www.microvt.com Email: hightechyoung@yahoo.com 作者:HighTech Young

4. 设置 Struct member alignment 为 1 Byte. 选择 Project -> Settings…把 Settings for 下拉列表框切换 到 All Configurations.选择选项卡 C/C++, category 下拉列表框切换到 Code Generation, Struct 把 从 。 member alignmen 下拉列表框中选择 1 Byte(如图 6-9)

图 6-9 设置 Struct member alignment 为 1 Byte

5. 选择运行库。选择 Project -> Settings…把 Settings for 下拉列表框切换到 All Configurations.选择选 项卡 C/C++,把 category 下拉列表框切换到 Code Generation,从 Use run-time library 下拉列表框中 选择 Multithreaded DLL(如图 6-10) 。

图 6-10 选择运行库 7

该文档版权归上海微视泰科工作室所有,转载请注明出处! 网址:http://www.microvt.com Email: hightechyoung@yahoo.com 作者:HighTech Young

6. 为

lvsbutil 设置 Custom Build 命令。选择 Project -> Settings…把 Settings for 下拉列表框切换到 All

Configurations.选择选项卡 Custom Build。在 <Cintools 目录的路径>\lvsbutil

Commands 域中填写以下内容(其中
–d $(WkspDir)\$(OutDir)

代表空格):

$(TargetName)

例如:D:\cintools\lvsbutil $(TargetName) –d $(WkspDir)\$(OutDir)
此处<Cintools 目录的路径>是指向 LabVIEW 安装目录中 cintools 目录的路径。 但是由于编译器不识别长文 件名,所以此处的路径比须是 DOS 操作系统的路径名(即目录和文件名 8 字符,后缀名 3 字符的格式) ,否则编译 时会出错。建议将整个 Cintools 目录 copy 到一个容易用 DOS 命名方式表达的路径下来使用,如 d:\cintools。

在 Outputs 域中填写以下内容:
$(OutDir)$(TargetName).lsb

为编译两数求和的例子所作配置如图 6-11 所示。

图 6-11 为 lvsbutil 设置 Custom Build 命令

7. 最后将 C 源文件添加进项目中来进行编译。添加 C 源文件的方法可参看第 2 步。编译成功后即可生 成.lsb 文件。 6.2.4. 为 CIN 加载.lsb 文件 为了在 VI 中调用 CIN,还要完成加载 CIN 目标代码的最后一步。可以通过选择 CIN 节点右键菜单中 Load Code Resource…来加载相应.lsb 文件,一旦加载成功,此 VI 就可以脱离源文件单独运行了。如果用户升 级了代码,只需要重新加载新的.lsb 文件即可。 6.2.5. CIN 的调试 编写复杂的 CIN 代码很难一次成功,一般需要反复调试才能完成。调试 CIN 可以使用以下两种方法。 一种通过配置 VC++开发环境以便能在设计时对代码调试,另一种是使用 DbgPrintf 函数显示变量运行时信
8

该文档版权归上海微视泰科工作室所有,转载请注明出处! 网址:http://www.microvt.com Email: hightechyoung@yahoo.com 作者:HighTech Young

息。 (1) 使用 DbgPrintf 函数显示变量运行时信息 DbgPrintf 函数与 SPrintf 函数类似,其函数原型如下:
Int32 DbgPrintf(CStr cfmt, ..);

在运行时,如果第一次执行它时,会弹出一个窗口显示传递给该函数的值,随后的调用会在窗口中添 加新的行。如果传递参数 NULL 给该函数时窗口会关闭。 (2) 配置 VC++开发环境以便能在设计时对代码调试 为了能在设计时利用 VC++调试 CIN,必须按照下面步骤来进行。 a. 在 CIN 源代码中设置中断。中断必须在 CIN 被加载进内存后设置。这可以通过在 CINLoad 函数种 添加 asm int 3;汇编代码来进行,代码如下:
CIN MgErr CINLoad(RsrcFile reserved) { Unused(reserved); asm int 3; /*DebugBreak();*/ return noErr; }

在 Windows 2000/XP 平台上可以使用 头文件
#include <windows.h>

DebugBreak();代替汇编代码行,但是应该包含 windows.h

CIN MgErr CINLoad(RsrcFile reserved) { Unused(reserved); DebugBreak(); return noErr; }

b. 重新创建带有中断的 CIN 如果用户使用的 Makefile 编译项目,只要在.lvm 文件中添加下面两行,然后重新创建项目:
… DEBUG = 1 cinLibraries = Kernel32.lib …

如果用户使用 VC++ IDE 编译项目则按照下面方法对项目进行配置: 1) 指 定 LabVIEW 为 调 用 所 调 试 DLL 项 目 的 可 执 行 执 行 程 序 。 打 开 项 目 , 选 择 Projects->Settings 将 Settings For 下拉列表框设置为 Win32 Debug;选择 Debug 选项卡,将 Category 下拉列表框设置为 General;在 Executable for debug session 域中输入(或浏览) LabVIEW 可执行文件的路径后选择 OK;
9

该文档版权归上海微视泰科工作室所有,转载请注明出处! 网址:http://www.microvt.com Email: hightechyoung@yahoo.com 作者:HighTech Young

为 Active Configuration;选择 Win32 Debug 然后点 OK 关闭 Set Active Project Configuration 窗口再重 新创建项目 c. 最后如果用户是使用 Makefile 编译项目,则正常运行程序,当其运行到中断处时会弹出如下信息:
Click Cancel to launch the debugger, which attaches to LabVIEW, searches for the DLLs, then asks for the source file of your CIN.

2) 配置

Win32 Debug。选择 Build->Set Active Configuration,设置 Win32 Debug

此时用户便可以调试源文件了。 如果用户使用 VC++ IDE 编译项目, 则可以在源文件中任何位置设置断点, 将项目配置设置为 Debug 然后运行即可调试。 6.2.6. 关于 CIN 的其它知识点 前面几节只是对 LabVIEW 中 CIN 的开发方法作了介绍。但是要出色的完成 CIN 开发其实还有其它几 个方面的知识需要了解,这里只对这些知识点简要介绍,详细介绍请参考 LabVIEW 随机手册。 (1) 使 LabVIEW 以多线程方式运行 CIN。如果 LabVIEW 将以多线程方式运行 CIN,则 CIN 节点 的颜色为黄色,负责为橙色。为了让 LabVIEW 以多线程方式处理 CIN,用户要在 C 源文件中 添加下面函数的原型声明和代码:
CIN MgErr CINProperties(int32 prop, void *data); … CIN MgErr CINProperties(int32 prop, void *data) { switch (prop) { case kCINIsReentrant: *(Bool32 *)data = TRUE; return noErr; } return mgNotSupported; }

(2) 使 CIN 为线程安全。CINProperties 只能保证 LabVIEW 以多线程的方式运行 CIN,至于 CIN 是否能真正线程安全,则取决于 C 代码的编写。下面给出一些基本的代码线程安全特点。 a. 代码不含有未受保护的全局数据(如全局变量,文件) ; b. 代码不访问硬件(即不含有寄存器一级的代码) ; c. 代码不调用非线程安全的函数、DLL 或者驱动; d. 代码使用信号量或者互斥量来保护全局量; e. 代码不用 CIN 的现场管理函数来访问全局资源等。 (3) LabVIEW 管理函数。 LabVIEW 有一套移植性很好的函数集可以通过 CIN 调用, 其实 LabVIEW 本身就基于这些函数之上来实现用户的需求。这些函数包括内存管理,文件管理以及其它的支持 函数(如位操作,字节转换等) 。用户可以同过调用这些函数开发与平台无关的程序。此外 LabVIEW 的分析函数主要基于 CIN 创建,所以用户可以直接调用这些函数。
10


相关文章:
LabVIEW与C语言程序的接口设计
但它提供了 CIN(Code Interface Node) 节点。 用户可在 LabVIEW 中确定 CIN ...C+ 5.0 IDE 编译设计代码,具体操作过程如下: (1)创建一个新的 DLL 项目。...
Labview调用C语言、Matlab脚本节点以及库函数节点的方...
Labview 调用 C 语言的方法 CIN(Code InterfaceNode...它与动态链接库的不同之处在于,它能够将代码集成在...在 LabVIEW 项目中调用.dll 中的函数。创建如图所示...
LabVIEW的VI转换为C语言代码
LabVIEW的VI转换为C语言代码_计算机软件及应用_IT/计算机_专业资料。如何 ...只需要在刚才的代码生成贵发上 点击右键。Generate C Code 就可以了。 注意:...
LabVIEW与其他计算机语言接口技术
CIN 是“Code Interface Node”的简称。由于在“Advanced”子模板上提供的 CIN 图标 可以实现在 LabVIEW 中引入 C 语言源代码,因此,它是 LabVIEW 图像化编程语言...
基于C语言的虚拟仪器系统开发
分析并实现了 摘要 LabVIEWC 语言接口的高级...code interface node(CIN) words: 所谓虚拟仪器,就...在虚拟仪器系统开发中若遇到这类问题,就可利用虚拟...
Labview实验指导书
(Code Interface Node)节点使得用户可以使用由 C 或 C++ 语言等编写的程序模块...interface nodes)现 存的 VHDL 代码与 IP 核心集成到 LabVIEW 应用程序中; ...
LabVIEW与C接口设计
但它提供了 CIN(Code Interface Node)节点。用户可在 LabVIEW 中确定 CIN 节点的入口与出口参数个数类型,在 C 编译环境下,生成.lsb 文件,然后在 LabVIEW 中对...
在LabVIEW中驱动数据采集卡的三种方法
子 VI 、 LabVIEW 的 Functions 模板内 Adevanced 中有一个 CIN(Code InteRFace Node)图标,用来 在 LabVIEW 程序方框图中直接调其它编程语言(如 VC)写的代码...
LabVIEW论文
利用它组 建仪器测试系统和数据采集系统可以大大简化...(Code)而 LabVIEW 则是使用图形化程序设计语言 G ...(C Interface Node) 节点使得用户可以使用由 C 或...
lalabview
子 VI LabVIEW 的 Functions 模板内 Adevanced 中有一个 CIN (Code Interface Node) 图标, 用来在 LabVIEW 程序方框图中直接调其它编程语言(如 VC)写的代码。...
更多相关标签:
node js interface | labview formula node | labview node | labview invoke node | 集成system interface | labview error code | labview code 50103 | labview开发qr code |