示例#1
0
        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);
        }
示例#2
0
        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);
        }