简单,并且处理很快,就在回调函数中直接处理即可,如果需要花费较长的时间,你就需要建立数据缓冲区,先将数据填入缓冲区,然后直接返回,同时建立单独的线程来处理缓冲区的数据,这当中需要注意缓冲区的同步 *** 作保护
例如,你的界面程序调用通信模块,在界面程序中设置了回调用来响应通信模块中接收到的数据,在处理时将收到的数据显示在界面上,对于数据量较少的情形,你直接在回调中将收到的数据抛出消息给主界面刷新即可;对于数据量很大的场合,你直接抛消息很可能会失败,而且每次收到数据都触发界面刷新会严重降低性能,那么就需要先将数据填入缓冲区,主界面以定时读取数据的方式来刷新
另外,虚机团上产品团购,超级便宜
使用 LoadLibrary 载入动态链接库
取得dll中提供的函数地址, Func_Gato_Keypad_SetUploadMsgCallBack
调用该函数
动态链接库用完使用FreeLibrary卸载掉
int my_msg_callback(char ipAddr, GATO_MSG_TYPE MsgType, GATO_UPLOAD_MSG_T UploadMsg, void pUserdata)
{
print("msg");
}
void main()
{
Func_Gato_Keypad_SetUploadMsgCallBack fnSetCallback;
HINSTANCE hDll = LoadLibrary("dllpathname");
if(hDll)
{
fnSetCallback= (Func_Gato_Keypad_SetUploadMsgCallBack )GetProcAddress( hDll, "Func_Gato_Keypad_SetUploadMsgCallBack" );
}
if(fnSetCallback)
fnSetCallback(iKeypadID, my_msg_callback, pUseData);
if(hDll)
FreeLibrary(hDll);
}
在C语言中,函数只能返回一个值,要返回两个值,可以改换思路,通过其它方式做到。
1 建立数组,返回指针。
在要返回的两个值类型相同时,可以用创建数组的方式,将要返回的值存在数组中,并返回数组首地址,这样就可以实现返回两个值的效果。
需要注意的是,要返回数组首地址,那么返回的值不可以是局部变量,有如下几种是可以的:
a) 使用静态局部变量存储,并返回地址;
b) 使用全局变量存储,返回地址;
c) 函数中动态分配内存,并返回申请到的地址,此种方法需要注意,在使用后需要释放;
d) 在参数中传入数组地址,并返回。即返回的实际上是主调函数中的变量地址。
2 建立结构体,返回结构体变量。
将需要返回的值,写成结构体形式,并返回结构体变量,这样可以实现一个返回值中含有多组数据。
3 当数据规模较小时,可以采用将小规模数据合并为大规模数据的方式,进行返回。
比如,需要返回两个char型数据时,可以通过返回一个short数据,高地位分别存储各自的值。
除以上方法外,还可以不使用返回值的方式,而是通过函数参数传值,或者全局变量传值等方式,将要返回的值回传给主调函数。
可以的,前提是你要定义一个回调函数原型,然后你就自由了,只要符合原型的函数都可以作为回调函数使用。
定义方法:
typedef (返回值类型) 回调名 (参数1类型,参数2类型)
例如:
typedef double (PF)(double dbData, int iSize);
在Windows的SYSTEMDRV驱动程序中提供了几个鲜为人知的系统计时器函数(这几个函
数未写入Windowsh中,但却被SYSTEMDRV输出了),这几个函数可以帮助我们获得精
确计时器服务,即系统计时器。这其中最重要的是CreateSystemTimer()和
KillSystemTimer(),这两个函数允许我们安装异步计时器的回调函数(Callback),有
些类似于在DOS环境中截取INT 8中断处理程序。这个回调是真正异步的,完全避开了
Windows的消息工具,因而具有重要意义。事实上,Microsoft Excel和Windows COMM
驱动程序都用到了系统计时器,而由SetTimer()安装的一般计时器也是由系统计时器
来实现的。
这两个函数的原型如下:�
WORD CreateSystemTimer(wMsecInterval,lpfnTimerProc);�
WORD wMsecInterval; /以毫秒为单位的时间间隔,系统将每隔此时间调用一 次回调函数
/�
FARPROC lpfn TimerProc;/指向回调函数的指针/�
WORD KillSystemTimer(hTimer);�
WORD hTimer;/欲释放的系统计时器句柄/�
其中,CreateSystemTimer()用于安装一个系统计时器回调函数,SYSTEM INT8处理程序将
按wMsecInterval指定的时时间间隔调用此回调函数。当然,这个指定的回调频率也是有
限的,同SetTimer()一样,每秒钟调用回调函数次数不能超过182次,即wMsecInterval>
55。该函数返回一个系统计时器句柄。若安装失败,则返回NULL。KillSystemTimer()则
用于撤销一个已安装的系统计时器hTimer。若成功,则返回;出错则返回传给它的参数
hTimer。�
3使用系统计时器应注意的问题。�
系统计时器回调函数虽然不是中断处理程序,但由于它直接被中断处理程序调用,因此也
必将它看作中断代码。这也就决定了在使用过程中必须注意以下几个问题:�
(1)在回函数中应包括尽量少的代码,以使得频繁回调的该函数不至于占用太多的CPU时
间。一般情况下,系统计时器总是用来监视或设置某些变量的值。�
(2)由于该回调函数属于中断代码,因此大多数Windows API函数调用都不适用了,只有
几个简单的函数仍然可以使用,如PostMessage(),GetCurrentTask()和MessageBeep()
等。�
(3)由于该回调函数由中断处理程序直接调用,因此该函数必须放在一个固定的代码段
中,并且调用前必须装载DS寄存器,这可由形实替换函数MakeProcInstance()来做到。�
另外,由于这两个函数在Windowsh中没有给出(即Windows缺省输入库不含此两函数),因
此在调用之前必须进行链接。这可采用运行时动态链接,即通过GetModuleHandle()和
GetProcAddress()来链接;也可在程序模块定义文件中用IMPORTS语句来引入,此时则必
须在程序源文件中说明CreateSystemTimer()和KillSystemTimer()为外部函数。本文给出
的例子采用第二种方案。
如何调用C语言写的库,如alib等,有对应的库头文件ah。假设ah中定义了函数:
int
WhyCoding(int
a,
float
b);
做法是,
/
cpp_ah
/
extern
"C"
{
#include
"ah"
}
或
/
cpp_ah
/
extern
"C"
{
int
WhyCoding(int
a,
float
b);
/
重定义所有的C函数
/
}
从上面可以看出,extern
"C"
是用在C和C++之间的桥梁。之所以需要这个桥梁是因为C编译器编译函数时不带
函数的类型信息,只包含函数符号名字,如C编译器把函数int
a(float
x)编译成类似_a这样的符号,C连接器只要
找到了调用函数的符号,就可以连接成功,它假设参数类型信息是正确的,这是C编译连接器的缺点。而C++
编译器为了实现函数重载,编译时会带上函数的类型信息,如他把上面的a函数可能编译成_a_float这样的
符号为了实现重载,注意它还是没有带返回值得信息,这也是为什么C++不支持采用函数返回值来区别函数
重载的原因之一,当然,函数的使用者对函数返回值的处理方式(如忽略)也是重要原因。
基于以上,C调用C++,首先需要用封装函数把对C++的类等的调用封装成C函数以便C调用,于是extern
"C"
的
作用是:让编译器知道这件事,然后以C语言的方式编译和连接封装函数(通常是把封装函数用C++编译器按C++
方式编译,用了extern
"C"
后,编译器便依C的方式编译封装接口,当然接口函数里面的C++语法还是按C++方式
编译;对于C语言部分--调用者,还是按C语言编译;分别对C++接口部分和C部分编译后,再连接就可以实现C
调用C++了)
相反,C++调用C函数,extern
"C"
的作用是:让C++连接器找调用函数的符号时采用C的方式,即使用_a而不是
_a_float来找调用函数。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)