• <small id='aoK5c'></small><noframes id='aoK5c'>

      <bdo id='aoK5c'></bdo><ul id='aoK5c'></ul>
    <legend id='aoK5c'><style id='aoK5c'><dir id='aoK5c'><q id='aoK5c'></q></dir></style></legend>

    1. <i id='aoK5c'><tr id='aoK5c'><dt id='aoK5c'><q id='aoK5c'><span id='aoK5c'><b id='aoK5c'><form id='aoK5c'><ins id='aoK5c'></ins><ul id='aoK5c'></ul><sub id='aoK5c'></sub></form><legend id='aoK5c'></legend><bdo id='aoK5c'><pre id='aoK5c'><center id='aoK5c'></center></pre></bdo></b><th id='aoK5c'></th></span></q></dt></tr></i><div id='aoK5c'><tfoot id='aoK5c'></tfoot><dl id='aoK5c'><fieldset id='aoK5c'></fieldset></dl></div>
      1. <tfoot id='aoK5c'></tfoot>

        如何将委托或函数指针从 C# 传递到 C++ 并使用 InternalCall 调用它

        时间:2023-11-11

              <tbody id='fAjfy'></tbody>
            <i id='fAjfy'><tr id='fAjfy'><dt id='fAjfy'><q id='fAjfy'><span id='fAjfy'><b id='fAjfy'><form id='fAjfy'><ins id='fAjfy'></ins><ul id='fAjfy'></ul><sub id='fAjfy'></sub></form><legend id='fAjfy'></legend><bdo id='fAjfy'><pre id='fAjfy'><center id='fAjfy'></center></pre></bdo></b><th id='fAjfy'></th></span></q></dt></tr></i><div id='fAjfy'><tfoot id='fAjfy'></tfoot><dl id='fAjfy'><fieldset id='fAjfy'></fieldset></dl></div>
          1. <tfoot id='fAjfy'></tfoot>

              1. <legend id='fAjfy'><style id='fAjfy'><dir id='fAjfy'><q id='fAjfy'></q></dir></style></legend>

                  <bdo id='fAjfy'></bdo><ul id='fAjfy'></ul>

                  <small id='fAjfy'></small><noframes id='fAjfy'>

                • 本文介绍了如何将委托或函数指针从 C# 传递到 C++ 并使用 InternalCall 调用它的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  我在 C# 中有以下设置:

                  I have the following setup in C#:

                  public delegate void CallbackDelegate(string message);
                  [MethodImplAttribute(MethodImplOptions.InternalCall)]
                  public static extern void setCallback(CallbackDelegate aCallback);
                  
                  public void testCallbacks()
                  {
                      System.Console.Write("Registering C# callback...
                  ");
                      setCallback(callback01);
                  }
                  
                  public void callback01(string message)
                  {
                      System.Console.Write("callback 01 called: " + message + "
                  ");
                  }
                  

                  这在 C++ 中(该函数通过 mono_add_internal_call 正确注册):

                  And this in C++ (the function is registered correctly via mono_add_internal_call ):

                  typedef void (*CallbackFunction)(const char*);
                  void setCallback(MonoDelegate* delegate)
                  {
                      // How to convert the MonoDelegate to a proper function pointer?
                      // So that I can call it like func("test");
                  }
                  

                  调用 C++ 函数并将 something 传递给委托变量.但是现在呢?

                  The C++-function is called and something is passed to the delegate variable. But what now?

                  我环顾四周,发现函数mono_delegate_to_ftnptr"被提到了几次,从这些例子来看,它似乎正是我所需要的.
                  然而,这个函数在我的mono(4.6)发行版中似乎根本不存在,所以我只能猜测它不再存在了.

                  I looked around and found the function "mono_delegate_to_ftnptr" mentioned a few times, and from those examples it seems to be exactly what I need.
                  However, this function simply does not seem to exist in my distribution of mono (4.6), so I can only guess it does not exist any more.

                  我还找到了一些如何使用 PInvoke 执行此操作的示例.这是我不想使用的东西 - 因为 InternalCall 对于我的目的来说要快得多.
                  当然,如果 PInvoke 是唯一的方法,那就这样吧,但我对此表示怀疑.

                  I also found a few examples of how to do this with PInvoke. Which is something I do not want to use - since InternalCall is much faster for my purpose.
                  Of course, if PInvoke would be the only way, so be it, but I doubt that.

                  到最后,我真的不知道如何从这里开始.

                  In the end, I am really at a loss at how to proceed from here.

                  推荐答案

                  经过几个小时的挖掘,我终于找到了一个(?)解决方案.
                  基本上,适用于 PInvoke 方法的方法在这里也适用,您可以将函数指针而不是委托从 C# 传递到 C(++).
                  我更喜欢一个可以直接传递委托的解决方案,但你总是可以在 C# 中添加一些包装器代码,至少让它看起来像这样.

                  After some more hours of digging I finally found a (the?) solution.
                  Basically, what works for the PInvoke approach works here as well, you can pass a function pointer instead of a delegate from C# to C(++).
                  I'd prefer a solution where you can pass a delegate directly, but you can always add some wrapper code in C# to at least make it look like that.

                  解决方案:

                  C#:

                  public delegate void CallbackDelegate(string message);
                  [MethodImplAttribute(MethodImplOptions.InternalCall)]
                  public static extern void setCallback(IntPtr aCallback);
                  
                  private CallbackDelegate del; 
                  public void testCallbacks()
                  {
                      System.Console.Write("Registering C# callback...
                  ");
                      del = new CallbackDelegate(callback01);
                      setCallback(Marshal.GetFunctionPointerForDelegate(del));
                  
                      System.Console.Write("Calling passed C++ callback...
                  ");
                  }
                  
                  public void callback01(string message)
                  {
                      System.Console.Write("callback 01 called. Message: " + message + "
                  ");
                  }
                  

                  C++:

                  typedef void (*CallbackFunction)(MonoString*);
                  void setCallback(CallbackFunction delegate)
                  {
                      std::cout << &delegate << std::endl;
                      delegate(mono_string_new(mono_domain_get(), "Test string set in C++"));
                  }
                  

                  但请注意:您需要以某种方式将委托保留在 C# 中(这就是我将其分配给del"的原因),否则它将被 GC 捕获并且您的回调将变得无效.
                  当然,这是有道理的,但我觉得在这种情况下很容易忘记.

                  Watch out, though: You need to keep the delegate around in C# somehow (which is why I assigned it to "del") or it will be caught by the GC and your callback will become invalid.
                  It makes sense, of course, but I feel this is easy to forget in this case.

                  这篇关于如何将委托或函数指针从 C# 传递到 C++ 并使用 InternalCall 调用它的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  上一篇:进展如何&lt;T&gt;不同于Action&lt;T&gt;?(C#) 下一篇:传递带有额外参数的委托函数

                  相关文章

                  <small id='0yvaV'></small><noframes id='0yvaV'>

                • <legend id='0yvaV'><style id='0yvaV'><dir id='0yvaV'><q id='0yvaV'></q></dir></style></legend>
                • <i id='0yvaV'><tr id='0yvaV'><dt id='0yvaV'><q id='0yvaV'><span id='0yvaV'><b id='0yvaV'><form id='0yvaV'><ins id='0yvaV'></ins><ul id='0yvaV'></ul><sub id='0yvaV'></sub></form><legend id='0yvaV'></legend><bdo id='0yvaV'><pre id='0yvaV'><center id='0yvaV'></center></pre></bdo></b><th id='0yvaV'></th></span></q></dt></tr></i><div id='0yvaV'><tfoot id='0yvaV'></tfoot><dl id='0yvaV'><fieldset id='0yvaV'></fieldset></dl></div>
                  • <bdo id='0yvaV'></bdo><ul id='0yvaV'></ul>
                  1. <tfoot id='0yvaV'></tfoot>