ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

c# – 将字符串从非托管代码传递给托管

2019-06-20 13:55:21  阅读:181  来源: 互联网

标签:c marshalling unmanaged com-interop managed


我将字符串从非托管代码传递给托管有问题.
在我的非托管类(unmanagedClass.cpp)中,我有一个指向托管代码函数的指针:

TESTCALLBACK_FUNCTION testCbFunc;

TESTCALLBACK_FUNCTION接受一个字符串并且不返回任何内容:

typedef void (*TESTCALLBACK_FUNCTION )(char* msg);

非托管类继承自ITest接口,该接口只有一个方法:

    STDMETHOD(put_TestCallBack) (THIS_
                  LPVOID FnAddress       
             ) PURE;

在managedClass.cs中,我编写了这段代码:

public class ManagedClass
{
    ITest unmanaged = new unmanagedClass();
    public delegate void TestDelegate(string info);
    ManagedClass()
    {
        unmanaged.put_TestCallBack(new TestDelegate(this.Test));
    }
    void Test(string info)
    {
            MessageBox.Show(info);
    }
}

[ComImport, Guid("<my guid here>")]
public class unmanagedClass
{
}

[ComImport, System.Security.SuppressUnmanagedCodeSecurity,
Guid("<my guid here>"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ITest
{
    [PreserveSig]
    int put_TestCallBack([MarshalAs(UnmanagedType.FunctionPtr), In] Capture.TestDelegate func);

}

要从非托管代码调用Test func,我使用它

(*testCbFunc)("Func Uragan33::Execute has been started!");

但是当调用来自managedClass.cs的Test方法时,我总是收到空字符串.
为什么会这样?

预先感谢!

解决方法:

您在调用约定上不匹配. C代码中的typedef声明了一个带有默认调用约定的函数指针,即__cdecl.但是托管代码中委托的默认值是__stdcall.

你需要一个属性告诉pinvoke marshaller.看起来像这样:

    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    public delegate void TestDelegate(string info);

在函数声明中删除[MarshalAs].修复C代码中的typedef可能更好,如果可以的话,明确地使所有内容保持一致是首选解决方案:

    typedef void (__stdcall * TESTCALLBACK_FUNCTION )(char* msg);

不相关,这是一个你需要修复的错误:

   unmanaged.put_TestCallBack(new TestDelegate(this.Test));

您创建的委托对象对垃圾收集器不可见.如果将在下一个GC上收集,则当本机代码进行回调时,您的代码将崩溃.您必须将委托对象存储在某处,以便GC始终看到引用.要么作为类中的字段,要求类对象需要保持足够长的时间,要么保持静态变量.

请注意当您声明回调接口而不是委托时,所有这些问题是如何消失的. COM的方式.

标签:c,marshalling,unmanaged,com-interop,managed
来源: https://codeday.me/bug/20190620/1244936.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有