99网
您的当前位置:首页DLL调用

DLL调用

来源:99网
NI LabWindows CVI 中调用 DLL 的几种方法

NI LabWindows CVI 中调用 DLL 的几种方法

NI LabWindows CVI 是一个很好的编程工具,用它的人门槛要求不是很高(比VC++好多了)漂亮的立体界面,标准C的编程语言……。当我转向它的时候,我发现这就是传说中真正的RAD工具,但国内关于这方面的书不多,遇到问题后连个能商量的人都没几个,却是同并快乐着。

这几日上网发现CVI的讨论者多了,也发现有很多CVI友们提出了一些困惑,比如用CVI加载别的编程语言写的DLL时遇到的无法使用的问题。

首先是 extern \"C\",CVI中无法加载有此类声明的DLL(有一些人发表的关于CVI加载DLL的文章中居然说必需有extern \"C\"声明,CVI才能用DLL)。然后用CVI生成的有“DLLSTDCALL”字样的DLL VC不认识!。难到CVI这东西真是好用不便宜??? 我以前也遇到过同样的问题,今天把我总结的一些解决办法拿出来与大家分享。 1、和盘托出

简单点说就是把你的CVI工程编成DLL,由其它(如VC)去调用。有些朋友会问:CV作的DLL中能用界面吗,如何作?

当然是可以有界面的,先Build->Target Type->Dynamic Link Library,再Build->Target Setting->Embed project .UIRs。这样就能把你的UIR也打包进去了。 例程如下: #include

//这是CVI标准DLL MAIN函数 static int panelHandle;

int __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); }

//注意下面的代码

void __stdcall RunDllUI (void) {

panelHandle = LoadPanelEx (0, \"dlluir.uir\PANEL, __CVIUserHInst);//这里你应该看明白了吧!

DisplayPanel (panelHandle); RunUserInterface (); }

int CVICALLBACK CloseUICallback (int panel, int control, int event, //在DLL中控件的回调函数

void *callbackData, int eventData1, int eventData2) //正常使用 {

switch (event) {

case EVENT_COMMIT: HidePanel(panelHandle); DiscardPanel(panelHandle); QuitUserInterface(0); break; }

return 0; }

//…………………… 2、拖泥带水

在DLL中是可以加载其它DLL的,那些用VC作的不是给CVI用的DLL我们当然无法使用(VC中有太多的关键字CVI中无法识别),不过用VC识别它自已的程序还是没问题的,我们用VC新建一个DLL工程,然后加载那些我们想用的DLL,在新工程里写几个CVI能用的函数实现对其它DLL的通讯接口,编译,过关!

3、孤注一掷

有些朋友会说:VC 不会!我连VC的IDE界面都不认识! 那么我们就只能在CVI内部解决DLL的问题了! 请看例程:

#include //我们需要WINDOWS的API函数 #include #include #include

//请注意,在以上的“#include”语句中,我们没有加入DLL的头文件

//因为就是加了才无法通过编译,这里我们用一种处理无头案的方法来解决那些非我族类的DLL int status;

char message[80];

int main (int argc, char *argv[]) {

/*请注意以下几个声明,它们可是很重要的!!!*/ HMODULE hinstLib;

DLLCdeclFunction DLLFunction;

BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;

/*-------------------------------------------------------------------------------------------------------*/

if (InitCVIRTE (0, argv, 0) == 0) /* Needed if linking in external compiler; harmless otherwise */

return -1; /* out of memory */

/*-------------------------------------------------------------------------------------------------------*/

// Get a handle to the DLL module. //装载动态链接库mydll.dll

hinstLib = LoadLibrary(\"mydll.dll\");

// If the handle is valid, try to get the function address. if (hinstLib != NULL)//成功装载动态链接库mydll.dll {

DLLFunction = (DLLCdeclFunction)GetProcAddress(hinstLib, (LPCSTR)\"MyDLLCdeclFunction\"); //取函数指针地址

// If the function address is valid, call the function.

if (fRunTimeLinkSuccess = (DLLFunction != NULL)) //dll中有函数MyDL

LCdeclFunction() {

Fmt(message, \"message via DLL function\\n\");

status = (long int)DLLFunction (message);//调用dll函数!!! }

// Free the DLL module

fFreeResult = FreeLibrary(hinstLib);//卸载动态链接库mydll.dll }

// If unable to call the DLL function, use an alternative if (! fRunTimeLinkSuccess) {

MessagePopup (\"Function Load Error\"); }

/*-------------------------------------------------------------------------------------------------------*/ return 0; }

通过以上的代码你应该明白它是如何工作的了吧! 这是MyDLLCdeclFunction的函数原形:

extern \"C\" long int DLLIMPORT MyDLLCdeclFunction(char * dummycharname);

DLLFunction 是指向函数的指针 message 是传给该函数的参数 status 是该函数的返回值 4、乘龙快婿

新出的CVI 8.5有了一个新特性:可以用在Visual.Studio.2005的VC中新建、添加CVI的工程

这样对于在CVI中使用DLL我们又有了一个新的思路,把作好的CVI用VC2005打开,然后在VC中加载DLL给CVI使用!但是实际作了以后,你会发现当你在VC2005中在CVI的头文件中“#include \"mydll.h\" ”后,编译器会给出与CVI下同样的错误提示! 解决的办法也有:我们可以在VC2005内先加载CVI工程,可以看到都是“*.h *.c”文件,用“Add new file to Item”在工程内新加一个“*.cpp”及“*.h”,现在在新加的文件里再调用之前的头文件及DLL看看结果如何?

5、移情别恋

JAVA中有一种JNI技术可以在JAVA中调用DLL,也同样可以把JAVA作成DLL。我们看一下在JAVA中调用DLL的方法: 我们要在JAVA中调用hello.dll JAVA代码: class HelloWorld {

public native void displayHelloWorld(); static {

System.loadLibrary(\"hello\");//此句重要 }

public static void main(String[] args) { new HelloWorld().displayHelloWorld(); } } 编译!

javac HelloWorld.java //得到HelloWorld.class javah HelloWorld // 得到 HelloWorld.h

这个h文件相当于我们在java里面的接口,这里声明了一个Java_HelloWorld_displayHelloWorld (JNIEnv *, jobject);方法,然后在我们的本地方法里面实现这个方法,也就是说我们在编写C/C++程序的时候所使用的方法名必须和这里的一致 VC代码:

#include

2 #include \"HelloWorld.h\" 3 #include

4 JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld(JNIEnv *env, jobject obj) {

printf(\"Hello world!\\n\"); return; }

生成动态库!

运行程序

java HelloWorld 屏幕输出:Hello world!

因篇幅问题不能全部显示,请点此查看更多更全内容