gpt4 book ai didi

c# - 如何使用语义类型编码 size_t 跨平台

转载 作者:行者123 更新时间:2023-11-30 21:03:19 24 4
gpt4 key购买 nike

根据我的理解,MarshalAsAttribute(UnmanagedType.SysUInt) 应该将特定于平台的无符号整数类型(32 或 64 字节)编码为托管类型 (ulong)。

     /// Return Type: size_t->unsigned int
///bgr: uint8_t*
///width: int
///height: int
///stride: int
///output: uint8_t**
[DllImportAttribute("libwebp.dll", EntryPoint = "WebPEncodeLosslessBGR")]
[return: MarshalAsAttribute(UnmanagedType.SysUInt)]
public static extern ulong WebPEncodeLosslessBGR([InAttribute()] IntPtr bgr, int width, int height, int stride, ref IntPtr output);

但它不起作用 - 我收到此错误:

Cannot marshal 'return value': Invalid managed/unmanaged type combination (Int64/UInt64 must be paired with I8 or U8).

我知道I can switch the return type to IntPtr ,但这对使用我的 API 的人来说非常不直观。

为什么 SysUInt 不工作?

最佳答案

您可以使用 UIntPtr 使 PInvoke 方法保持私有(private),并使用您喜欢的签名实现另一个方法,该方法调用 PInvoke 正确映射所有内容,并且这个方法是公开的:

/// Return Type: size_t->unsigned int
///bgr: uint8_t*
///width: int
///height: int
///stride: int
///output: uint8_t**
public static ulong WebPEncodeLosslessBGR([InAttribute()] IntPtr bgr, int width, int height, int stride, ref IntPtr output)
{
return (ulong)_WebPEncodeLosslessBGR(bgr, width, height, stride, ref output);
}

[DllImportAttribute("libwebp.dll", EntryPoint = "WebPEncodeLosslessBGR")]
[return: MarshalAsAttribute(UnmanagedType.SysUInt)]
private static extern UIntPtr _WebPEncodeLosslessBGR([InAttribute()] IntPtr bgr, int width, int height, int stride, ref IntPtr output);

当框架变得难以处理时……就不要使用它们。编码很痛苦,我倾向于只使用我已经知道的东西......其他一切,我只是四处走动。

编辑

它不起作用,因为编码(marshal)拆收器不够聪明,无法看到每个 SysUInt 类型都适合 ulong 类型。它正在检查返回值,与参数相同。

的确,您不能将 ulongSysUInt 用于参数,但您可以用于返回……只是不明白其中的区别。 =\

有哪些替代方案?

UIntPtr 似乎是最佳选择...但还有其他选择:使用接口(interface) ICustomMarshaler 实现自定义编码(marshal)拆收器...并使用 UnmanagedType.CustomMarshaler:

[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(CustomMarshalerType))]

ICustomMarshaler 实现

通过 ICustomMarshaler 的这个实现,您可以做您想做的事。我没有测试它,因为我没有非托管库来进行测试,但它很简单,而且非常简单……所以我认为它会按原样运行,无需任何更改。如果没有,请发表评论,我会修改它。

public class CustomMarshalerType : ICustomMarshaler
{
public object MarshalNativeToManaged(IntPtr pNativeData)
{
return (ulong)Marshal.ReadIntPtr(pNativeData).ToInt64();
}

public IntPtr MarshalManagedToNative(object ManagedObj)
{
throw new InvalidOperationException();
}

public void CleanUpNativeData(IntPtr pNativeData)
{
}

public void CleanUpManagedData(object ManagedObj)
{
}

public int GetNativeDataSize()
{
return IntPtr.Size;
}
}

关于c# - 如何使用语义类型编码 size_t 跨平台,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12966283/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com