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);
        }
Exemplo n.º 2
0
        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;
            }
              }
        }