none
c++对象怎么使用非托管的对象的回调函数? delegate和函数指针怎么转换? RRS feed

  • 问题

  • 我要调用一个别人写的dll,这个dll是用非托管的c++写的,它需要调用者注册回调函数,以回调函数的方式不停返回结果。
    它还有几百个自定义的非托管的数据结构,调用的时候会用得到。

    我的上层程序用的是c#,专门建了个C++的dll项目打算把非托管dll包一层(混编),此dll对上层的接口都采用托管的方式,然后又会在内部调用非托管的dll来完成功能。
    现在遇到的问题是:
     C#用的是delegate,非托管dll采用的是函数指针,这两者在C++ dll里(混编)不知道怎么才能转换,试了一些方法都不行。
    谁能帮帮我?

    config->algorithmFun的类型:
     public delegate void voidFun();

    reader->cb_doAlgo的类型(reader是非托管对象):
     typedef void *CB_doAlgo();

    这样转换不了(土法炼钢):
     reader->cb_doAlgo=(CB_doAlgo)config->algorithmFun;

    错误信息:
     error C2066: cast to function type is illegal
     error C2440: 'type cast' : cannot convert from 'AlgorithmicTrading::Struct::CommonDelegates::voidFun ^' to 'AlgorithmicTrading::Struct::CB_doAlgo (__cdecl *)'
      Conversion from delegate type to function pointer type is not allowed
     error C2659: '=' : function as left operand

    2011年5月25日 2:42

答案

全部回复

  • 你需要在非托管段里把这些值读出来,然后转程托管变量,在调用事件,触发代理。也就是说你要做一个中间者,接到非托管回调后,触发托管代理。


    麻烦把正确答案设为解答。
    2011年5月25日 3:10
    版主
  • 你好 SplendourG,接到非托管回调后,触发托管代理这个方法之前我试过的,但是编译报错。
    下面代码中"QuationReader"是托管的类(我想把它当做中间者,承上启下),Reader是非托管的类,config->algorithmFun指向的是上层c#代码的delegate:
      [StructLayout(LayoutKind::Sequential)]
    public ref class QuationReader
    {
      private:
        Reader* reader;
    
      public:
        QuatationOperConfig^ config;
    
        ~QuationReader()
        {
          delete reader;
        }
    
        void Start(void)
        {
          reader=new Reader(); 
    
          reader->cb_doAlgo=&QuationReader::doAlgo;
          //reader->cb_doAlgo=(CB_doAlgo)config->algorithmFun;
    
          reader->Start();
        }
        void doAlgo()
        {
          config->algorithmFun();
        }
    };
    
     
    但是编译的时候出现错误:
    error C3374: can't take address of 'AlgorithmicTrading::QuationReader::doAlgo' unless creating delegate instance
    这个错误指向代码中"reader->cb_doAlgo=&QuationReader::doAlgo;"这句
    看它的意思是说在托管类中不能使用函数指针?(虽然我设了LayoutKind::Sequential这个属性)
     
     
    2011年5月25日 5:36
    • 已标记为答案 bitfish_jzl 2011年5月27日 11:37
    2011年5月26日 3:18
    版主
  • 解决了! 哈哈

    参考了这个贴子:http://blog.csdn.net/wangchibest/archive/2008/12/01/3420789.aspx

    其实Marshal自己提供了两个函数,可以很方便地在delegate和Function pointer之间转换:

        Marshal::GetFunctionPointerForDelegate
        Marshal::GetDelegateForFunctionPointer

    ^_^ 

    版主给的贴子我也看了一下,比较复杂,先用简单的 :)

    • 已标记为答案 bitfish_jzl 2011年5月27日 11:37
    2011年5月27日 11:36