private static PInvokeMap GetLinkFlags(NativeMethodAttributeBase nativeMethodAttr) { PInvokeMap linkFlags = 0; if (nativeMethodAttr.ExactSpelling) { linkFlags |= PInvokeMap.NoMangle; } switch (nativeMethodAttr.CallingConvention) { case CallingConvention.Winapi: linkFlags |= PInvokeMap.CallConvWinapi; break; case CallingConvention.Cdecl: linkFlags |= PInvokeMap.CallConvCdecl; break; case CallingConvention.StdCall: linkFlags |= PInvokeMap.CallConvStdcall; break; case CallingConvention.ThisCall: linkFlags |= PInvokeMap.CallConvThiscall; break; case CallingConvention.FastCall: linkFlags |= PInvokeMap.CallConvFastcall; break; } switch (nativeMethodAttr.CharSet) { case CharSet.None: linkFlags |= PInvokeMap.CharSetNotSpec; break; case CharSet.Ansi: linkFlags |= PInvokeMap.CharSetAnsi; break; case CharSet.Unicode: linkFlags |= PInvokeMap.CharSetUnicode; break; case CharSet.Auto: linkFlags |= PInvokeMap.CharSetAuto; break; } return(linkFlags); }
private static MethodBuilder GeneratePInvokeMethod(TypeBuilder typeBuilder, string dllName, MethodInfo setPInvokeDataMethod, object runtimeModule, MethodInfo setTokenMethod, MethodInfo method, NativeMethodAttributeBase nativeMethodAttr, ParameterInfo[] methodParams, Type[] parameterTypes) { MethodBuilder pInvokeMethodBuilder = typeBuilder.DefineMethod( "PIvk_" + method.Name, MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.PinvokeImpl | MethodAttributes.HideBySig, CallingConventions.Standard, method.ReturnType, parameterTypes); // Set PInvokeData. var entryName = nativeMethodAttr.EntryPoint ?? method.Name; var token = pInvokeMethodBuilder.GetToken(); PInvokeMap linkFlags = GetLinkFlags(nativeMethodAttr); setPInvokeDataMethod.Invoke(null, new object[] { runtimeModule, dllName, entryName, token.Token, (int)linkFlags }); setTokenMethod.Invoke(pInvokeMethodBuilder, new object[] { token }); // Add PreserveSig to the method implementation flags. // NOTE: If this line is commented out, the return value will be zero when the method is invoked. pInvokeMethodBuilder.SetImplementationFlags(pInvokeMethodBuilder.GetMethodImplementationFlags() | MethodImplAttributes.PreserveSig); var returnParameter = pInvokeMethodBuilder.DefineParameter(0, method.ReturnParameter.Attributes, null); var returnParameterAttrs = CustomAttributeData.GetCustomAttributes(method.ReturnParameter); foreach (var attr in returnParameterAttrs) { returnParameter.SetCustomAttribute(CreateAttributeBuilder(attr)); } for (int i = 0; i < methodParams.Length; i++) { var p = methodParams[i]; var paramBuilder = pInvokeMethodBuilder.DefineParameter(i + 1, p.Attributes, p.Name); foreach (var paramAttr in CustomAttributeData.GetCustomAttributes(p)) { paramBuilder.SetCustomAttribute(CreateAttributeBuilder(paramAttr)); } } // The PInvoke method does not have a method body. return(pInvokeMethodBuilder); }