从托管的.NET代码调用本机回调(使用COM加载托管代码时)

时间:2010-05-27 22:23:41

标签: c# .net com interop com-interop

我对本机/托管互操作的大量错误信息感到困惑。

我有一个常规的C ++ exe,它不是使用CLR构建的(它既不是托管C ++也不是C ++ / CLI,永远不会)。这个C ++ exe是“负责人”,它没有托管包装。

我想从C ++ exe中访问C#程序集中的一些代码。我可以使用COM从我的C ++代码访问C#程序集。但是,当我的C#代码检测到一个事件时,我希望它回调我的C ++代码。将在运行时提供要回调的C ++函数指针。请注意,C ++函数指针指向exe执行环境中的函数。它可以使用那里的静态成员。我不希望托管代码尝试加载一些DLL来调用函数(没有DLL)。

如何通过COM / .NET将此C ++函数指针传递给我的C#代码并让我的C#代码成功调用它?

谢谢!

2 个答案:

答案 0 :(得分:7)

您可能想要使用Marshal.GetDelegateForFunctionPointer

  1. 创建与本机函数签名匹配的委托类型,记住编组类型的正确方法并根据需要使用MarshalAs
  2. 将本机代码中的本机函数指针与C#代码进行通信,但您可以(在您的情况下,看起来您可以使用COM - > C#连接)
  3. 使用Marshal.GetDelegateForFunctionPointer将指针转换为C#-callable delegate
  4. 使用您的参数
  5. 调用委托 张俊峰举了一个例子here

    请注意MSDN上提到的限制:

      

    GetDelegateForFunctionPointer   方法有以下限制:

         
        
    • 互操作不支持泛型   场景。
    •   
    • 您无法传递无效功能   指向此方法的指针。
    •   
    • 您只能将此方法用于纯粹   非托管函数指针。
    •   
    • 您无法使用此方法   通过C ++获得的函数指针   或者来自GetFunctionPointer方法。
    •   
    • 您无法使用此方法创建   从函数指针委托   另一位管理代表。
    •   

    关于C ++的部分可能是指类方法的函数指针。这仍应适用于全球职能。

答案 1 :(得分:4)

标准COM方法是订阅由COM服务器引发的事件。使用可以在C#中使用event关键字,CLR interop自动实现所需的COM粘贴。在C ++代码中使用IConnectionPoint接口。背景资料is here