我是不是需要在 C# 中使用来自非托管 C++ dll 的原始数据类型执行 MarshalAs?
Posted
技术标签:
【中文标题】我是不是需要在 C# 中使用来自非托管 C++ dll 的原始数据类型执行 MarshalAs?【英文标题】:Do I need to do MarshalAs with primitive data types from unmanaged C++ dll in C#?我是否需要在 C# 中使用来自非托管 C++ dll 的原始数据类型执行 MarshalAs? 【发布时间】:2018-05-28 04:34:03 【问题描述】:我有一个基本问题,
我有一个 C++ 非托管 dll,它具有带参数的函数输入和输出一些无符号字符、无符号短、无符号长、有符号字符、有符号短、有符号长数据类型。
我需要对其进行编组还是直接映射它? 如果有的话,最佳做法是什么?
例如 dll
unsigned long SomeFunc(unsigned char variableA);
C#(C# 中的直接映射)
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.U4)]
public static extern uint SomeFunc(byte variableA);
【问题讨论】:
指定一个已经是默认选择的 UnmanagedType 通常不是问题。但是您确实选择了一个默认值并不总是 U4 的。long
在 64 位模式下很棘手,它在 Windows 上是 U4,但在 unix 上是 U8。如果此代码必须是可移植的,那么您会倾向于修改 C++ 声明。
感谢您的评论。但我真的不明白你。您能否提供链接或对此进行更多解释,以便我更好地理解。我真的很想知道对此的最佳做法是什么。
【参考方案1】:
大多数数据类型在托管和非托管内存中都有一个共同的表示,并且不需要互操作封送处理程序进行特殊处理。这些类型被称为 blittable 类型,因为它们在托管和非托管代码之间传递时不需要转换。
MSDN:https://docs.microsoft.com/en-us/dotnet/framework/interop/blittable-and-non-blittable-types
【讨论】:
如果你链接新版本更好(msdn.microsoft.com/en-us/library/75dwhxf7(v=vs.100).aspx)...旧版本忘记了float
和double
。
那么,这行代码够用了吧? [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern uint SomeFunc(byte variableA);
@nutcracker 如果您在 Windows 中工作,并且方法是 cdecl(它没有标记为 stdcall),那么可以。【参考方案2】:
为了扩展mozfox的响应,列表是:byte
、sbyte
、short
、ushort
、int
、uint
、long
、ulong
、IntPtr
,UIntPtr
,float
,double
,其中的一维数组([]
),其中的struct
。缺少bool
(可以通过各种方式编组)、char
(不要问为什么......我不知道)、string
。
【讨论】:
以上是关于我是不是需要在 C# 中使用来自非托管 C++ dll 的原始数据类型执行 MarshalAs?的主要内容,如果未能解决你的问题,请参考以下文章