用C++实现了一个回调函数接口的DLL,然后在C#的Form里面调用
C++的部分代码:
|
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#里面调用
|
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的
|
1
2
3
4
5
6
|
private
static
MyDllCall callbackfun;
private
void
Btn_SetCallBack_Click(
object
sender, EventArgs e)
{
callbackfun = DoWhileGetMsg;
APISetCallback(callbackfun);
}
|
谢谢
C++与C#跨语言调用DLL实现代理问题解决

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

被折叠的 条评论
为什么被折叠?



