private static void EmitStringReturnMarshalling(ILGenerator ilGenerator, IMethodReference ptrToStringAnsi, IMethodReference ptrToStringUnicode, StringFormatKind charSet, IMarshallingInformation returnTypeInfo) { bool doUnicodeMarshalling = false; if (returnTypeInfo != null && returnTypeInfo.UnmanagedType == UnmanagedType.LPWStr) { doUnicodeMarshalling = true; } else if (charSet == StringFormatKind.Unicode) { if (returnTypeInfo == null || (returnTypeInfo.UnmanagedType != UnmanagedType.LPStr && returnTypeInfo.UnmanagedType != UnmanagedType.LPTStr)) { doUnicodeMarshalling = true; } } ilGenerator.Emit(OperationCode.Call, doUnicodeMarshalling ? ptrToStringUnicode : ptrToStringAnsi); }
internal PlatformInvokeInformation(ITypeDeclarationMember declaringMember, SourceCustomAttribute dllImportAttribute) { this.importModule = Dummy.ModuleReference; this.importName = declaringMember.Name.Name; this.noMangle = false; this.pinvokeCallingConvention = PInvokeCallingConvention.WinApi; this.stringFormat = StringFormatKind.Unspecified; this.useBestFit = null; this.throwExceptionForUnmappableChar = null; INameTable nameTable = dllImportAttribute.ContainingBlock.NameTable; int bestFitMappingKey = nameTable.GetNameFor("BestFitMapping").UniqueKey; int callingConventionKey = nameTable.GetNameFor("CallingConvention").UniqueKey; int charSetKey = nameTable.GetNameFor("CharSet").UniqueKey; int entryPointKey = nameTable.GetNameFor("EntryPoint").UniqueKey; int exactSpellingKey = nameTable.GetNameFor("ExactSpelling").UniqueKey; int setLastErrorKey = nameTable.GetNameFor("SetLastError").UniqueKey; int throwOnUnmappableCharKey = nameTable.GetNameFor("ThrowOnUnmappableChar").UniqueKey; foreach (Expression expr in dllImportAttribute.Arguments) { CompileTimeConstant cc = expr as CompileTimeConstant; if (cc != null && cc.Value is string) { IName moduleName = expr.NameTable.GetNameFor((string)cc.Value); this.importModule = new Immutable.ModuleReference(dllImportAttribute.ContainingBlock.Compilation.HostEnvironment, new ModuleIdentity(moduleName, string.Empty)); continue; } NamedArgument narg = expr as NamedArgument; if (narg == null) continue; int key = narg.ArgumentName.Name.UniqueKey; if (key == bestFitMappingKey) { if (narg.ArgumentValue.Value is bool) this.useBestFit = (bool)narg.ArgumentValue.Value; continue; } if (key == callingConventionKey) { if (narg.ArgumentValue.Value is int) { switch ((CallingConvention)(int)narg.ArgumentValue.Value) { case CallingConvention.C: this.pinvokeCallingConvention = PInvokeCallingConvention.CDecl; break; case CallingConvention.Standard: this.pinvokeCallingConvention = PInvokeCallingConvention.StdCall; break; case CallingConvention.ExplicitThis: this.pinvokeCallingConvention = PInvokeCallingConvention.ThisCall; break; case CallingConvention.FastCall: this.pinvokeCallingConvention = PInvokeCallingConvention.FastCall; break; } } continue; } if (key == charSetKey) { if (narg.ArgumentValue.Value is int) { switch ((CharSet)(int)narg.ArgumentValue.Value) { case CharSet.Ansi: this.stringFormat = StringFormatKind.Ansi; break; case CharSet.Auto: this.stringFormat = StringFormatKind.AutoChar; break; case CharSet.Unicode: this.stringFormat = StringFormatKind.Unicode; break; } } continue; } if (key == entryPointKey) { string/*?*/ importName = narg.ArgumentValue.Value as string; if (importName != null) { this.importName = nameTable.GetNameFor(importName); } continue; } if (key == exactSpellingKey) { if (narg.ArgumentValue.Value is bool) this.noMangle = (bool)narg.ArgumentValue.Value; continue; } if (key == setLastErrorKey) { if (narg.ArgumentValue.Value is bool) this.supportsLastError = (bool)narg.ArgumentValue.Value; continue; } if (key == throwOnUnmappableCharKey) { if (narg.ArgumentValue.Value is bool) this.throwExceptionForUnmappableChar = (bool)narg.ArgumentValue.Value; continue; } } }