从C++转入C#,费了好大劲,绊子是一个接着一个,又遇如下问题:
软件主界面、数据库部分为C#代码,底层通信为C++代码,封装在动态库中,
本来以为这样挺合理,可是数据库部分让人头疼,
因为C++通信部分也涉及到数据库,不知该如何解决,
我是这样想的:C#代码提供回调函数给C++,
当C++底层需要查询数据库时,调用此回调函数,
让C#函数查询数据库并返回数据供C++使用,
这样C++就不用直接和数据库打交道了,
否则C#代码与数据库有联系(其中多线程访问数据库用了很多同步对象),
C++代码也和数据库建立连接访问数据库很不爽(C++也不能用C#的同步对象啊)。不知我的想法如何,更为重要的是,
我开这个帖子的主题是想问:C#如何提供回调函数供C++代码调用?
软件主界面、数据库部分为C#代码,底层通信为C++代码,封装在动态库中,
本来以为这样挺合理,可是数据库部分让人头疼,
因为C++通信部分也涉及到数据库,不知该如何解决,
我是这样想的:C#代码提供回调函数给C++,
当C++底层需要查询数据库时,调用此回调函数,
让C#函数查询数据库并返回数据供C++使用,
这样C++就不用直接和数据库打交道了,
否则C#代码与数据库有联系(其中多线程访问数据库用了很多同步对象),
C++代码也和数据库建立连接访问数据库很不爽(C++也不能用C#的同步对象啊)。不知我的想法如何,更为重要的是,
我开这个帖子的主题是想问:C#如何提供回调函数供C++代码调用?
是这个意思吧,
让C#给C++留个接口吧,很多的,WEbService, Romting,WCF,甚至让C#写个dll让 C++调用也行。
C#通过p/invoke调用赋值函数为函数指针赋值,C#中定义一个delegate可以作为函数指针写入。
放弃这个思路吧。我的想法是:通过sendmessage实现底层C++和应用层C#数据查询的同步。底层需要查询数据库时,则发消息给应用层,然后应用层查询数据,然后底层读取数据。方案二:
如果你能把底层单独运行的话,可以用进程通讯实现,remoting。
实际上就是用C怎么处理dll的函数指针,C#也怎么处理,只不过改成了p/invoke和delegate。
[DllImport("coredll.dll", EntryPoint = "waveInOpen", SetLastError = true)]
private static extern int waveInOpen(ref IntPtr t, uint id, ref WaveFormat_GSM pwfx, WAVEINPROC dwCallback, uint dwInstance, uint fdwOpen);
public delegate void WAVEINPROC(IntPtr hdrvr, int uMsg, int dwUser, ref WaveHdr wavhdr, int dwParam2);
WAVEINPROC waveinproc;
private void Form1_Load(object sender, EventArgs e)
{
waveinproc = onwaveinproc;
waveInOpen(ref m_hWaveIn, uint.MaxValue, ref waveformatEx, waveinproc, 0, 0x00030000);
}
private void onwaveinproc(IntPtr hdrvr, int uMsg, int dwUser, ref WaveHdr wavhdr, int dwParam2)
{
//.....
} 例如这个,是去年开发wince对讲系统的代码片断,其中onwaveinproc就是录音缓冲区满之后调用的C#回调函数。
C++里,就用一个函数指针来接收那个委托的参数,在需要调用的时候调用那函数指针
SendMessage就不用了吧,我想同步处理,例如需要时就回调函数取得数据库数据,
方法二不行,我底层是动态库。
多的情况可以声明一个符合COM规范(继承IUnknown)的接口,然后让C#实现
这个接口,最后把对象通过COMInterop扔给C++用.以上方法要么需要C++程序导出函数,要么需要C++或C#一方去实现或调用那
堆烦得要命的COM.而且同9L所说,数据类型的转换也会是一个很烦的问题,你
可能不得不自己处理一些C++数据类型到.net类型的转换.如果你只是想把已有的C++代码利用起来,那么直接把它迁移到C++/CLI吧.这
样该死的PInvoke/COMInterop都可以见鬼去了.直接调用delegate就行了.
#include <stdio.h>extern "C"
{
__declspec(dllexport) void NativeMethod(void (__stdcall *pCallback)(WCHAR *wChar))
{
printf((*pCallback)(1,2));
}
}
在C#中调用 并把CALLBACK作为委托传过去//CALLBACK函数
private int Add(int a, int b)
{
return a+b;
}//声明委托
delegate int AddCallback(int a, int b);//调用c
static Main()
{
//声明一个回调委托
AddCallback callback=newAddCallback(Add); //调用C
NativeMethod(callback);
}//声明C函数原型
[DllImport("自己写")]
private static extern NativeMethod(delegate callback);