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
How do I marshal a structure as a pointer to a structure?
提问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.LPStruct
is rarely, if ever, the correct MarshalAs
argument. 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
ref
or 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。