你可以保持PInvoke的方法私用UIntPtr
,並實現與您的首選簽名的另一種方法,能正確調用的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);
當框架變得難處理...只是不要使用它們。編組是一種痛苦,我傾向於只使用我已經知道的事情......其他所有事情,我只是走開。
編輯
它不工作,因爲封送是不是足夠聰明,看到每一個SysUInt
類型的ulong
類型相符。它正在檢查回報,就像參數一樣。
確實,您不能使用ulong
和SysUInt
作爲參數,但是您可以返回......它看起來並不明智。 = \
還有什麼替代方案?
UIntPtr
似乎是最好的選擇......但也有其他的選擇:實現自定義封送,使用界面ICustomMarshaler
...和使用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;
}
}
'UIntPtr'肯定是正確的類型。你爲什麼要'ulong'? –
語義,它是一個公共API。 –
您可以在公共API中使用size_t –