c#导出C++回调函数(cici)

370 篇文章 6 订阅
259 篇文章 4 订阅

http://hi.baidu.com/tease/blog/item/1fe7213802780f22b9998f5a.html

 

c#导出C++回调函数(cici)

最近在公司做一个新的项目,由于C#做界面是非常快速的,于是决定用C#重写C++的界面,而原来的C++动态链接库是不需要修改的。只需要调用一下就可以了。
在调用过程中发现C++有回调函数,于是翻开MSDN终于发现,回调函数是使用委托来调用。
比如:
在C++中的回调函数是这样定义的:
typedef void (*CiCiCallBack) (bool started, void* client,char *message);

导出函数这样定义:
extern "C" _declspec(dllexport) bool Test(char* fileName, CiCiCallBack callback)
{
int n =10000;
MessageBoxExA(NULL,fileName,NULL,NULL,NULL);
callback(TRUE,&n, strcat(fileName, " hello world"));
return TRUE;
}

于是在C#中可以这样写:
public delegate void CiCiCallBack(bool started, IntPtr client,string msg);

[DllImport("CppCallBackDll.dll", EntryPoint = "Test", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Winapi)]
public static extern bool Test(string fileName, [In] CiCiCallBack callback);

在调用的时候这样调用:
CiCiCallBack callbackDelegate = new CiCiCallBack (CallBack);
Test(Application.ExecutablePath, callbackDelegate);

当然还得定义一个回调函数:
private void CallBack(bool flag, IntPtr client, string msg)
{
MessageBox.Show(msg, "", MessageBoxButtons.OK, MessageBoxIcon.Information);
}

理论上当执行到Test(Application.ExecutablePath, callbackDelegate);时候会自动调用回调函数。
但是实际却报出了这个错误:
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.

熟悉C++ 编程的人应该知道这个错误一般是由以下两种情况产生的:
1、参数传递有错误,尤其是指针传递的时候。
2、函数部分地方的约定不统一(压栈方式可能不统一)。
本文就是第二个原因,不难发现CPP中回调函数的约定和导出函数的约定是不统一的。于是强制在CPP代码中将回调函数定义为:
typedef void (_stdcall *CiCiCallBack) (bool started, void* client,char *message);
将导出函数修改为:
extern "C" _declspec(dllexport) bool _stdcall Test(char* fileName, CiCiCallBack callback)

对了,就是加了一个_stdcall得约定条件。_stdcall是Pascal程序的缺省调用方式,通常用于Win32 Api中,函数采用从右到左的压栈方式。

最后附上源代码。点击此处
CSharp 调用C++ DLL; 参数为指针类型导出函数 c# Csharp调用 c++库 参数为导入和导出指针两种 包含C++ DLL源码 如fun(cont char* A,char*B) A为输入参数,B为输出参数-C# CSharp call C++ DLL lib dll function param use export and import eg: fun(cont char* A,char*B) A IN,B OUT TestDll\Debug\TestCallDll.exe .......\.....\TestCallDll.vshost.exe .......\.....\TestCallDll.vshost.exe.manifest .......\.....\TestDll.dll .......\.....\TestDll.lib .......\TestCallDll\Form1.cs .......\...........\Form1.Designer.cs .......\...........\Form1.resx .......\...........\obj\Debug\TestCallDll.csproj.FileListAbsolute.txt .......\...........\...\.....\TestCallDll.csproj.GenerateResource.Cache .......\...........\...\.....\TestCallDll.exe .......\...........\...\.....\TestCallDll.Form1.resources .......\...........\...\.....\TestCallDll.pdb .......\...........\...\.....\TestCallDll.Properties.Resources.resources .......\...........\Program.cs .......\...........\...perties\AssemblyInfo.cs .......\...........\..........\Resources.Designer.cs .......\...........\..........\Resources.resx .......\...........\..........\Settings.Designer.cs .......\...........\..........\Settings.settings .......\...........\TestCallDll.csproj .......\....Dll\dllmain.cpp .......\.......\ReadMe.txt .......\.......\stdafx.cpp .......\.......\stdafx.h .......\.......\targetver.h .......\.......\TestDll.cpp .......\.......\TestDll.def .......\.......\TestDll.h .......\.......\TestDll.vcproj .......\.......\TestDll.vcproj.PC-201008261742.Administrator.user .......\TestDll.sln .......\TestDll.suo .......\....CallDll\obj\Debug\TempPE .......\...........\...\Debug .......\...........\obj .......\...........\Properties .......\Debug .......\TestCallDll .......\TestDll TestDll
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值