从C++转入C#,费了好大劲,绊子是一个接着一个,又遇如下问题:
软件主界面、数据库部分为C#代码,底层通信为C++代码,封装在动态库中,
本来以为这样挺合理,可是数据库部分让人头疼,
因为C++通信部分也涉及到数据库,不知该如何解决,
我是这样想的:C#代码提供回调函数给C++,
当C++底层需要查询数据库时,调用此回调函数,
让C#函数查询数据库并返回数据供C++使用,
这样C++就不用直接和数据库打交道了,
否则C#代码与数据库有联系(其中多线程访问数据库用了很多同步对象),
C++代码也和数据库建立连接访问数据库很不爽(C++也不能用C#的同步对象啊)。不知我的想法如何,更为重要的是,
我开这个帖子的主题是想问:C#如何提供回调函数供C++代码调用?

解决方案 »

  1.   

    http://social.msdn.microsoft.com/Forums/zh-CN/visualcshartzhchs/thread/6bcf46db-2c2a-4201-9d90-5476be1c0a4f
      

  2.   

    不用回调函数吧,你的意思就是如果C++的程序需要数据的时候从C#代码里取,
    是这个意思吧,
    让C#给C++留个接口吧,很多的,WEbService, Romting,WCF,甚至让C#写个dll让 C++调用也行。
      

  3.   

    你的C++程序要编译为dll,声明函数指针,再声明一个为该函数指针赋值的函数以供C#调用;
    C#通过p/invoke调用赋值函数为函数指针赋值,C#中定义一个delegate可以作为函数指针写入。
      

  4.   

    这个方法不妥。我做个很多C++和C#打交道的程序,感觉就是“不爽”,别扭。
    放弃这个思路吧。我的想法是:通过sendmessage实现底层C++和应用层C#数据查询的同步。底层需要查询数据库时,则发消息给应用层,然后应用层查询数据,然后底层读取数据。方案二:
    如果你能把底层单独运行的话,可以用进程通讯实现,remoting。
      

  5.   

    wince上的gpsapi.dll,在gps设备坐标更新时调用C#应用程序的回调函数,就是C#通过delegate为函数指针赋值,另外cellcore.dll等也都有很多地方是这种方式。
    实际上就是用C怎么处理dll的函数指针,C#也怎么处理,只不过改成了p/invoke和delegate。
      

  6.   


    [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#回调函数。
      

  7.   

    你的想法不错,但是实现起来十分困难,主要是C#返回的DataTable类型在C++中无法得到映射,C++数据源默认是啥类型我是不知道了
      

  8.   

    在C#里先要定义一个委托,然后使用这个委托来定义为一个参数来传给C++的导出函数
    C++里,就用一个函数指针来接收那个委托的参数,在需要调用的时候调用那函数指针
      

  9.   


    SendMessage就不用了吧,我想同步处理,例如需要时就回调函数取得数据库数据,
    方法二不行,我底层是动态库。
      

  10.   

    函数少的情况可以用PInvoke直接转成符合StdCall的回调函数指针给C++
    多的情况可以声明一个符合COM规范(继承IUnknown)的接口,然后让C#实现
    这个接口,最后把对象通过COMInterop扔给C++用.以上方法要么需要C++程序导出函数,要么需要C++或C#一方去实现或调用那
    堆烦得要命的COM.而且同9L所说,数据类型的转换也会是一个很烦的问题,你
    可能不得不自己处理一些C++数据类型到.net类型的转换.如果你只是想把已有的C++代码利用起来,那么直接把它迁移到C++/CLI吧.这
    样该死的PInvoke/COMInterop都可以见鬼去了.直接调用delegate就行了.
      

  11.   

    在C\C++中声明一个参数为函数指针的函数(假设你的CALLBACK函数参数为两个INT
    #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);