I have a method, which generates the P/Invoke function dynamically:
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)
The reason is, I can control the dll path easier.
But now I met a C function, which uses a function pointer:
CUresult cuOccupancyMaxPotentialBlockSize ( int* minGridSize, int* blockSize, CUfunction func, CUoccupancyB2DSize blockSizeToDynamicSMemSize, size_t dynamicSMemSize, int blockSizeLimit )
Where the type CUoccupancyB2DSize
is a function pointer of:
size_t(CUDA_CB* CUoccupancyB2DSize )( int blockSize )
So if I translate that type to Func<int, IntPtr>
, I got exception while generating the P/Invoke method:
System.Runtime.InteropServices.MarshalDirectiveException : Cannot marshal 'parameter #4': Generic types cannot be marshaled.
Is there any workaround? In normal P/Invoke, you can add [MarshalAs(UnmanagedType.FunctionPtr)]
to translate a delegate into a function pointer, but how to do that with dynamic P/Invoke method generation?