-1
我有一個方法,該方法產生P /動態調用函數:如何使用委託參數類型定義PInvokeMethod?
member private this.MakePInvokeMethod(dllName:string, entryName:string, callingConvention:CallingConventions,
returnType:Type, parameterTypes:Type[],
nativeCallConv:CallingConvention, nativeCharSet:CharSet) =
let typeBuilder = moduleBuilder.DefineType("__Internal.DynamicInterop." + entryName)
let methodBuilder = typeBuilder.DefinePInvokeMethod("Invoke", dllName, entryName, MethodAttributes.Static ||| MethodAttributes.PinvokeImpl,
callingConvention, returnType, parameterTypes, nativeCallConv, nativeCharSet)
methodBuilder.SetImplementationFlags(methodBuilder.GetMethodImplementationFlags() ||| MethodImplAttributes.PreserveSig)
typeBuilder.CreateType().GetMethod("Invoke", BindingFlags.Static ||| BindingFlags.NonPublic)
原因是,我可以控制dll路徑更容易。
但現在我遇到一個C函數,它使用一個函數指針:
CUresult cuOccupancyMaxPotentialBlockSize (int* minGridSize, int* blockSize, CUfunction func, CUoccupancyB2DSize blockSizeToDynamicSMemSize, size_t dynamicSMemSize, int blockSizeLimit)
凡類型CUoccupancyB2DSize
是一個函數指針:
size_t(CUDA_CB* CUoccupancyB2DSize)(int blockSize)
所以,如果我這種類型轉換爲Func<int, IntPtr>
,生成P/Invoke方法時發生異常:
System.Runtime.InteropServices.MarshalDirectiveException : Cannot marshal 'parameter #4': Generic types cannot be marshaled.
有沒有解決方法?在正常的P/Invoke中,可以添加[MarshalAs(UnmanagedType.FunctionPtr)]
將委託轉換爲函數指針,但如何使用動態P/Invoke方法生成?
通過與方法一起創建新的委託類型。可悲的是你不能使用'Action <>'或'Func <>'。 – xanatos
另一種方法是簡單地將函數指針視爲一個'IntPtr',但那麼你只是將'Marshal.GetFunctionPointerForDelegate'與'Action <>''''Func <>''具有相同的限制'' – xanatos
是更容易的方法來控制DLL路徑 –