labview实现Dll中的回调函数的调用
曾经困惑于labview 调用DLL中的函数,该DLL所调用的函数内部当发生一些事件时调用回调函数,用labview该去怎么实现。
假设Dll中有导出函数funcA(int a,int b ,int (*callback) (int,int)),导出函数funcA有三个参数,两个整形参数,一个函数指针(即回调函数),这个导出函数用labview去调用该如何实现。C语言的函数指针相当于labview的vi句柄,labview中Vi就是封装的函数,基于这样的思路,callback回调自己用labview 封装成Vi并留出参数接口,当在labview 中装载Dll并调用funcA时,将callback函数封装的Vi的句柄传给第三个参数,但是这样并没有成功过。那么又该如何去实现?
这两天没事上网搜索,发现讲这方面的几乎没有,唯一找到的线索是labview 好像不能直接通过子Vi的方式调用回调函数,但是可以通过另外写个Dll,在该DLL中写一个导出函数用于获取回调函数的地址(即函数指针),而所调用的回调函数也在该DLL中实现。下面就这样的思路来验证下。
一、写包含funcA函数的DLL,该函数的某个参数为回调函数的函数指针
在VS2015中新建win32项目MyDll
图1
应用程序类型选DLL,并勾选导出符号
图2
在MyDll.h中删除这几行代码(图a), 新增EXTERN_CMYDLL_API int _stdcall functionCall(int a, intb, int(*callback)(int,int)); 后如图(b)
图a
图b
在MyDll.cpp中删除这几行代码(图a),新增
usingnamespace std;
MYDLL_API int _stdcall functionCall(int a,intb,int(*callback)(int,int)){
int result;
result = callback(a,b)+10;
//cout<< "Call callback:"<< result << endl;
return result;
}
后如图(b)
图a
图b
运行生成MyDll.dll
二、写辅助DLL,该DLL中导出获取回调函数地址的函数,回调函数的实现也在该Dll中实现
同一,新建win32 DLL工程dllattach
将第一步生成的MyDll.dll和MyDll.h拷到dllattach的源代码所在目录下,并包含在工程中。直接拷过来的MyDll.h有可能提 示EXTERN_C错误,将其改为extern"C"即可
dllattach.h如下
#ifdefDLLATTACH_EXPORTS
#defineDLLATTACH_API __declspec(dllexport)
#else
#defineDLLATTACH_API __declspec(dllimport)
#endif
extern"C" DLLATTACH_API void*_stdcall getFunAdd(int);
dllattach.cpp如下
#include"stdafx.h"
#include<Windows.h>
#include<iostream>
#include<tchar.h>
#include"dllattach.h"
#include"MyDll.h"
int nummin(int ,int);
int nummax(int, int);
DLLATTACH_API void* _stdcall getFunAdd(int num){
switch(num)
{
case1:
return nummin;
break;
case2:
return nummax;
break;
default:
break;
}
return0;
}
int nummin(int a,intb){
int temp;
if(a>b){
temp =b;
}
else{
temp =a;
}
return temp;
}
int nummax(int a,intb){
int temp;
if(a>b){
temp =a;
}
else{
temp =b;
}
return temp;
}
运行工程生成dllattach.dll
三、通过labview调用DLL
新建labview Vi,保存为dllcall.vi,将前面生成的MyDll.dll和dllattach.dll拷到vi所在目录
dllcall.vi 后面板如图
dllcall.vi 前面板如图
dllattach.dll调用节点设置如下
MyDll.dll调用节点设置如下
该vi根据selector的值,当selector为1时result为num1和num2中的最小值加十,当selector为2时result为num1和num2中的最大值加十
如下运行结果
回调函数nummin(int a,int b)和nummax (int a,int b)都是在dllattach.dll自己实现了,dllattach.dll要的是导出一个获取回调函数的地址的导出函数,然后将函数地址传给呼叫回调函数的DLL调用节点。这种方法虽然麻烦了点但还是实现了。