で 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
引数にandを使用できないのは事実ですが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;
}
}