C# p/invoke C 函数返回指向结构的指针

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/779444/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 00:51:24  来源:igfitidea点击:

p/invoke C function that returns pointer to a struct

c#interoppinvoke

提问by THX-1138

How do I declare in C# a C function that returns a pointer to a structure?

如何在 C# 中声明一个返回指向结构的指针的 C 函数?

I believe following is one way to do that, followed by Marshal.PtrToStructureto get actual structure value.

我相信以下是一种方法,其次是Marshal.PtrToStructure以获得实际的结构值。

// C-function
SimpleStruct * Function(void);

// C# import
[DllImport("MyDll.dll")]
public static extern IntPtr Function();
  1. Am I correct about that?
  2. Are there other ways to accomplish the same? (It would be OK to get struct back by value)
  1. 我是否正确?
  2. 还有其他方法可以实现相同的目标吗?(按值取回 struct 就可以了)

采纳答案by Shea

Since the function returns a pointer (hopefully not a locally allocated one?) your best bet is to manually marshal it (via Marshal.PtrToStructure).

由于该函数返回一个指针(希望不是本地分配的指针?),您最好的办法是手动对其进行编组(通过Marshal.PtrToStructure)。

If it were a parameter you could create a managed version of the structure using the PInvoke Interop Assistant then pass it via ref or out.

如果它是一个参数,您可以使用 PInvoke Interop Assistant 创建结构的托管版本,然后通过 ref 或 out 传递它。

回答by Darren Kopp

I am not an expert here at all, but I happened to be looking at a piece of code (that i don't understand completely mind you) that is doing this same thing.

我根本不是这里的专家,但我碰巧正在看一段代码(我不完全理解)正在做同样的事情。

Here is what they are doing

这是他们在做什么

[DllImport("")]
private static extern short MethodName([In,Out] ref StructureName variable);

and then on the structure they have the following attribute

然后在结构上,它们具有以下属性

[StructLayout(LayoutKind.Sequential, Size = #)]
public struct StructureName {}

I think the part you are looking for is the [In,Out] part, and since it's being passed via ref, you should be getting the same data back.

我认为您正在寻找的部分是 [In,Out] 部分,因为它是通过 ref 传递的,所以您应该得到相同的数据。

marked as community wiki so people can fix this if wrong.

标记为社区维基,以便人们可以在错误时解决此问题。

回答by Eric Burnett

Caveat: this will only work if the pointer returned is to memory already managed by the CLR

警告:这仅在返回的指针指向已由 CLR 管理的内存时才有效

I believe what you are looking for is

我相信你正在寻找的是

// C# import
[DllImport("MyDll.dll")]
[return : MarshalAs(UnmanagedType.LPStruct)]
public static extern StructureName Function();

[StructLayout(LayoutKind.Sequential)]
public class StructureName {}

This should eliminate the need for any manual Marshal.PtrToStructurecalls. Depending on what your structure contains, you may need to tag some fields with MarshalAsattributes as appropriate. MSDNhas a good example of this.

这应该消除对任何手动Marshal.PtrToStructure调用的需要。根据您的结构所包含的内容,您可能需要MarshalAs适当地使用属性标记某些字段。MSDN有一个很好的例子。