返回从非托管指针托管代码

编程入门 行业动态 更新时间:2024-10-27 20:28:49
本文介绍了返回从非托管指针托管代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我有一个非托管的DLL导出如下因素的功能:

I've an unmanaged dll that exports the folowing function:

SomeData* test();

让我们假设SomeData为:

Let's assume SomeData as:

typedef struct _Data Data; struct _Data{ int a; int b; }

现在我想打电话给从C#代码此功能。我开始定义C#Struture需要这样的自定义编组:

Now i want to call this function from C# code. I start to define the C# Struture needed to custom marshaling like this:

[StructLayout(LayoutKind.Sequential)] public class SomeData { public Int32 a; public Int32 b; }

而现在,我宣布管理功能:

And now, i declare the managed function:

[DllImport("DynamicLibrary.dll", CharSet=CharSet.Auto)] [return: MarshalAs(UnmanagedType.LPStruct)] public static extern SomeData test();

和在主函数中我有:

IntPtr ptr = test();

这样做,我得到的MarchalDirectiveException:不能元帅返回值:无效的托管/非托管类型组合(智力/ UINT必须SysInt或SysUInt配对)。

Doing this, i get the MarchalDirectiveException: "Cannot marshal 'return value': Invalid managed/unmanaged type combination (Int/UInt must be paired with SysInt or SysUInt)."

我,因为我希望这记忆在C函数分配未分配的内存SomeData在C#和他们我会用Marshal.Copy将它传递给托管内存。

I did not allocate the memory for SomeData in C# since i expect this memory is allocated in the C function and them i would use the Marshal.Copy to pass it to the managed memory.

任何想法?谢谢

------------------------编辑完成后JaredPar答案​​------ --------------

------------------------ EDITED AFTER JaredPar ANSWER --------------------

其实,我的代码应付我的问题时犯的一个错误。我用的是真正的管理的​​签名是:

In fact, i committed a mistake when coping the code to my question. The real managed signature i was using was:

函数[DllImport(DynamicLibrary.dll,字符集= CharSet.Auto)]结果 [返回:的MarshalAs(UnmanagedType.LPStruct)结果公共静态外部的IntPtr测试();

[DllImport("DynamicLibrary.dll", CharSet=CharSet.Auto)] [return: MarshalAs(UnmanagedType.LPStruct)] public static extern IntPtr test();

JaredPar的答案仍然是相关的。为了得到正确的行为,我有2个选择:

The JaredPar's answer is still relevant. To get the right behaviour, i have 2 choices:

1)使用公共静态外部的IntPtr测试();'(无MarshalAs特性)签名,然后访问。回到像JaredPar指针提示

1) Use the 'public static extern IntPtr test();' (without MarshalAs attribute) signature and then access the returned pointer like JaredPar suggested.

2)使用公共静态外部SomeData测试();'(与MarshalAs特性),然后简单地使用SomeData SD =测试()

2) Use the 'public static extern SomeData test();' (with MarshalAs attribute) and then simply use SomeData sd = test();

推荐答案

在声明需要与参考值匹配指针类型的管理功能或的IntPtr 值。在这种情况下,LPStruct修改也无济于事。最简单的解决方法是测试的返回值转换成为一个的IntPtr ,而不是 SomeData ,因为本地方法将返回一个指针值。然后,您可以编写以下包装

When declaring the managed function you need to match pointer types with reference values or IntPtr values. In this case the LPStruct modifier won't help. The easiest solution is to convert the return value of test to be an IntPtr rather than SomeData since the native method is returning a pointer value. You can then write the following wrapper

[DllImport("DynamicLibrary.dll", CharSet=CharSet.Auto)] public static extern IntPtr test(); public static SomeData testWrapper() { var ptr = test(); try { return (SomeData)Marshal.PtrToStructure(ptr, typeof(SomeData)); } finally { // Free the pointer here if it's allocated memory } }

更多推荐

返回从非托管指针托管代码

本文发布于:2023-11-02 18:07:38,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1553052.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:指针   代码

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!