C# 如何将结构编组为指向结构的指针?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/827672/
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 03:14:45  来源:igfitidea点击:

How do I marshal a structure as a pointer to a structure?

c#pinvoke

提问by THX-1138

I am trying to pass a structure from C# into C++ library. I pass structure as an object, and C++ function expects it as a pointer (void *).

我正在尝试将结构从 C# 传递到 C++ 库。我将结构作为对象传递,而 C++ 函数将其作为指针(void *)。

I am having problem passing the structure.

我在传递结构时遇到问题。

[DllImport("MockVadavLib.dll", CharSet = CharSet.Ansi)]
public static extern IntPtr TheFunction([MarshalAs(UnmanagedType.LPStruct)] UserRec userRec);

Here is the run-time exception text I get:

这是我得到的运行时异常文本:

"Cannot marshal 'parameter #1': Invalid managed/unmanaged type combination (this value type must be paired with Struct)."

“无法封送‘参数#1’:无效的托管/非托管类型组合(此值类型必须与 Struct 配对)。”

Though I found an MSDN article that uses LPStruct in exactly this context.

尽管我发现了一篇 MSDN 文章,它正是在这种情况下使用了 LPStruct。

This is my structure I'm trying to marshal:

这是我试图编组的结构:

[StructLayout(LayoutKind.Sequential)]
public struct UserRec {
    [MarshalAs(UnmanagedType.I4)]
    public int userParam1;
}

This is C++ function:

这是 C++ 函数:

MOCKVADAVLIB_API tVDACQ_CallBackRec * TheFunction(void * userParams) {...

采纳答案by JaredPar

Try passing the structure as a ref parameter.

尝试将结构作为 ref 参数传递。

[DllImport("MockVadavLib.dll", CharSet = CharSet.Ansi)]
public static extern IntPtr TheFunction(ref UserRec userRec);

When you use a ref combined with a structure, it conceptually passes the address.

当您将 ref 与结构结合使用时,它在概念上会传递地址。

回答by Rytmis

Incidentally, UnmanagedType.LPStructis rarely, if ever, the correct MarshalAsargument. A quote from Adam Nathanwho is a Microsoft employee:

顺便说一句,UnmanagedType.LPStruct如果有的话,很少是正确的MarshalAs论点。来自微软员工Adam Nathan 的一句话

UnmanagedType.LPStruct is only supported for one specific case: treating a System.Guid value type as an unmanaged GUID with an extra level of indirection.

UnmanagedType.LPStruct 仅在一种特定情况下受支持:将 System.Guid 值类型视为具有额外间接级别的非托管 GUID。

回答by Joseph Lennox

Some additional information followup regarding @Rytmis's post.

关于@Rytmis 帖子的一些附加信息跟进。

From https://github.com/dotnet/runtime/blob/master/docs/coding-guidelines/interop-pinvokes.md:

https://github.com/dotnet/runtime/blob/master/docs/coding-guidelines/interop-pinvokes.md



Guids are usable directly in signatures. When passed by ref they can either be passed by refor with the [MarshalAs(UnmanagedType.LPStruct)]attribute.

[MarshalAs(UnmanagedType.LPStruct)]should onlybe used for by ref Guids.

指南可直接用于签名。当由 ref 传递时,它们可以由属性传递ref或与[MarshalAs(UnmanagedType.LPStruct)]属性一起传递。

[MarshalAs(UnmanagedType.LPStruct)]应该用于 ref Guids。