回调函数多次调用就出错

C++与C#跨语言调用DLL实现代理问题解决
本文详细介绍了如何在C++中定义回调函数接口并导出为DLL,然后在C#中通过P/Invoke调用此DLL,遇到代理对象垃圾回收引发的问题,并提供了解决方案。

用C++实现了一个回调函数接口的DLL,然后在C#的Form里面调用
C++的部分代码:

C/C++ code
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//声明
typedef  bool  (CALLBACK *CallbackHandler)( char  *sMsg);
CallbackHandler m_CrdHandler ;   //回复信息的回调函数
extern  "C" __declspec ( dllexport ) BOOL  WINAPI APISetCallback(CallbackHandler Info)
{
     m_CrdHandler = Info;
     return  TRUE;
extern  "C"  __declspec ( dllexport int  __stdcall APITestCall( char * sMsg)
{
     m_CrdHandler(sMsg);
     return  0;
}


然后在C#里面调用
C# code
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//声明
         public  delegate  void  MyDllCall( string  buf);         
  
         [DllImport( "D:\\xx\\xx\\xx.dll" , EntryPoint =  "APISetCallback" )]      
         static  extern  int  APISetCallback(MyDllCall fa);
          
         [DllImport( "D:\\xx\\xx\\xx.dll" , EntryPoint =  "APITestCall" )]    
         static  extern  int  APITestCall( string  sBuf);
         private  void  Btn_SetCallBack_Click( object  sender, EventArgs e)
         {
             APISetCallback(DoWhileGetMsg);
         }        
  
         //声明回调的函数
         public  void  DoWhileGetMsg( string  buf)
         {
             return ;   
             if  (buf ==  "" return ;
             System.IO.StreamWriter sw;
             sw =  new  System.IO.StreamWriter(sLogFile,  true );
             sw.WriteLine(DateTime.Now.ToString( "yyyy-MM-dd HH:mm:ss " ) +  "Client Get command:" );
             sw.WriteLine(buf);
             sw.Flush();
             sw.Close();
             return ;
         }
  
         private  void  Btn_TestCall_Click( object  sender, EventArgs e)
         {
             APITestCall(MsgBox1.Text);
         }


其实DoWhileGetMsg这个函数体里面那么多return就是调试的时候添加的,最后干脆什么都不执行,还是会出错,如下:

如果多次点击按钮(大概4,5十次),则会弹出对话框

对“FormsAppClt!FormsAppClt.Form1+MyDllCall::Invoke”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃
、损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们。  


解决了,原来是代理需要定义成static的

C# code
?
1
2
3
4
5
6
private  static  MyDllCall callbackfun;  
         private  void  Btn_SetCallBack_Click( object  sender, EventArgs e)
         {
             callbackfun = DoWhileGetMsg;
             APISetCallback(callbackfun);
         }       


谢谢  
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值