Пример #1
0
 private string WriteMarshalInputParameter(CppCodeWriter writer, MarshaledParameter parameter, IRuntimeMetadataAccess metadataAccess)
 {
     if (this.IsInParameter(parameter))
     {
         return(this._marshaler.WriteMarshalInputParameter(writer, parameter, this._parameters, metadataAccess));
     }
     return(this._marshaler.WriteMarshalEmptyInputParameter(writer, parameter, this._parameters, metadataAccess));
 }
Пример #2
0
        protected bool IsOutParameter(MarshaledParameter parameter)
        {
            TypeReference parameterType = parameter.ParameterType;

            if (parameter.IsOut && !parameterType.IsValueType())
            {
                return(true);
            }
            if (parameter.IsIn && !parameter.IsOut)
            {
                return(false);
            }
            return(parameter.ParameterType.IsByReference || MarshalingUtils.IsStringBuilder(parameterType));
        }
Пример #3
0
 private void WriteCleanupParameter(CppCodeWriter writer, string valueName, MarshaledParameter parameter, IRuntimeMetadataAccess metadataAccess)
 {
     if (this.ParameterRequiresCleanup(parameter))
     {
         if (this.IsInParameter(parameter))
         {
             this._marshaler.WriteMarshalCleanupParameter(writer, valueName, parameter, metadataAccess);
         }
         else
         {
             this._marshaler.WriteMarshalCleanupEmptyParameter(writer, valueName, parameter, metadataAccess);
         }
     }
 }
Пример #4
0
        protected string MarshaledArraySizeFor(string nativeArray, IList <MarshaledParameter> methodParameters)
        {
            switch (this._arraySizeSelection)
            {
            case ArraySizeOptions.UseArraySize:
                return(this._arraySize.ToString(CultureInfo.InvariantCulture));

            case ArraySizeOptions.UseSizeParameterIndex:
            {
                MarshaledParameter parameter = methodParameters[this._sizeParameterIndex];
                if (parameter.ParameterType.MetadataType == MetadataType.Int32)
                {
                    return(parameter.NameInGeneratedCode);
                }
                return($"static_cast<int32_t>({parameter.NameInGeneratedCode})");
            }

            case ArraySizeOptions.UseFirstMarshaledType:
                return($"static_cast<int32_t>({nativeArray}{this.MarshaledTypes[0].VariableName})");
            }
            throw new InvalidOperationException($"Unknown ArraySizeOptions: {this._arraySizeSelection}");
        }
Пример #5
0
 public override bool CanMarshalAsOutputParameter(MarshaledParameter parameter) =>
 base.MarshalInfoWriterFor(parameter).CanMarshalTypeToNative();
Пример #6
0
        protected bool IsInParameter(MarshaledParameter parameter)
        {
            TypeReference parameterType = parameter.ParameterType;

            return((!parameter.IsOut || parameter.IsIn) || (parameterType.IsValueType() && !parameterType.IsByReference));
        }
Пример #7
0
 private void WriteMarshalOutputParameter(CppCodeWriter writer, string valueName, MarshaledParameter parameter, IRuntimeMetadataAccess metadataAccess)
 {
     if (this.IsOutParameter(parameter))
     {
         this._marshaler.WriteMarshalOutputParameter(writer, valueName, parameter, this._parameters, metadataAccess);
     }
 }
Пример #8
0
 public DefaultMarshalInfoWriter MarshalInfoWriterFor(MarshaledParameter parameter) =>
 MarshalDataCollector.MarshalInfoWriterFor(parameter.ParameterType, this._marshalType, parameter.MarshalInfo, this._useUnicodeCharset, false, false, null);
Пример #9
0
 private bool ParameterRequiresCleanup(MarshaledParameter parameter) =>
 (this.IsInParameter(parameter) || parameter.IsOut);
Пример #10
0
 protected DefaultMarshalInfoWriter MarshalInfoWriterFor(MarshaledParameter parameter) =>
 this._marshaler.MarshalInfoWriterFor(parameter);
        private BlockSyntax CreateBodyFor(MethodDeclarationSyntax innerMethod, IEnumerable <MarshaledParameter> marshaledParameters, MarshaledParameter marshaledResult)
        {
            var body            = SyntaxFactory.Block();
            var finallyBlock    = SyntaxFactory.Block();
            var argsByParameter = innerMethod.ParameterList.Parameters.ToDictionary(
                p => p,
                p => ForwardParameter(p));
            var marshalerInitializers = new List <StatementSyntax>();
            var inputMarshaling       = new List <StatementSyntax>();
            var outputMarshaling      = new List <StatementSyntax>();

            var marshalersCreated = new HashSet <string>();
            Func <TypeSyntax, string> acquireMarshaler = type =>
            {
                var marshalerLocalName = Invariant($"_{type}");
                if (marshalersCreated.Add(marshalerLocalName))
                {
                    marshalerInitializers.Add(
                        SyntaxFactory.LocalDeclarationStatement(
                            SyntaxFactory.VariableDeclaration(ICustomMarshalerTypeSyntax)
                            .AddVariables(SyntaxFactory.VariableDeclarator(marshalerLocalName)
                                          .WithInitializer(SyntaxFactory.EqualsValueClause(
                                                               SyntaxFactory.InvocationExpression(
                                                                   SyntaxFactory.MemberAccessExpression(
                                                                       SyntaxKind.SimpleMemberAccessExpression,
                                                                       type,
                                                                       SyntaxFactory.IdentifierName("GetInstance")),
                                                                   SyntaxFactory.ArgumentList()))))));
                }

                return(marshalerLocalName);
            };

            foreach (var parameter in marshaledParameters)
            {
                string           marshalerLocalName = acquireMarshaler(parameter.MarshalerType);
                var              isOutParameter     = parameter.OriginalParameter.Modifiers.Any(m => m.IsKind(SyntaxKind.OutKeyword));
                TypeSyntax       localVarType       = isOutParameter ? parameter.OriginalParameter.Type : IntPtrTypeSyntax;
                ExpressionSyntax initialValue       = isOutParameter
                    ? (ExpressionSyntax)SyntaxFactory.DefaultExpression(parameter.OriginalParameter.Type)
                    : SyntaxFactory.InvocationExpression(
                    SyntaxFactory.MemberAccessExpression(
                        SyntaxKind.SimpleMemberAccessExpression,
                        SyntaxFactory.IdentifierName(marshalerLocalName),
                        SyntaxFactory.IdentifierName("MarshalManagedToNative")))
                                                      .AddArgumentListArguments(SyntaxFactory.Argument(SyntaxFactory.IdentifierName(parameter.OriginalParameter.Identifier)));
                var localVarIdentifier = SyntaxFactory.IdentifierName(Invariant($"_{parameter.OriginalParameter.Identifier.ValueText}"));
                inputMarshaling.Add(
                    SyntaxFactory.LocalDeclarationStatement(
                        SyntaxFactory.VariableDeclaration(localVarType)
                        .AddVariables(SyntaxFactory.VariableDeclarator(localVarIdentifier.Identifier)
                                      .WithInitializer(SyntaxFactory.EqualsValueClause(initialValue)))));

                argsByParameter[parameter.OriginalParameter] = argsByParameter[parameter.OriginalParameter]
                                                               .WithExpression(
                    isOutParameter
                            ? (ExpressionSyntax)localVarIdentifier
                            : SyntaxFactory.CastExpression(parameter.OriginalParameter.Type, localVarIdentifier));

                if (isOutParameter)
                {
                    outputMarshaling.Add(
                        SyntaxFactory.ExpressionStatement(SyntaxFactory.AssignmentExpression(
                                                              SyntaxKind.SimpleAssignmentExpression,
                                                              SyntaxFactory.IdentifierName(parameter.OriginalParameter.Identifier),
                                                              SyntaxFactory.CastExpression(
                                                                  parameter.FriendlyType,
                                                                  SyntaxFactory.InvocationExpression(
                                                                      SyntaxFactory.MemberAccessExpression(
                                                                          SyntaxKind.SimpleMemberAccessExpression,
                                                                          SyntaxFactory.IdentifierName(marshalerLocalName),
                                                                          SyntaxFactory.IdentifierName("MarshalNativeToManaged")),
                                                                      SyntaxFactory.ArgumentList(SyntaxFactory.SingletonSeparatedList(SyntaxFactory.Argument(
                                                                                                                                          SyntaxFactory.ObjectCreationExpression(
                                                                                                                                              IntPtrTypeSyntax,
                                                                                                                                              SyntaxFactory.ArgumentList(SyntaxFactory.SingletonSeparatedList(SyntaxFactory.Argument(localVarIdentifier))),
                                                                                                                                              null)))))))));
                }

                var cleanUpExpression = isOutParameter
                    ? (ExpressionSyntax)SyntaxFactory.ObjectCreationExpression(IntPtrTypeSyntax).AddArgumentListArguments(
                    SyntaxFactory.Argument(localVarIdentifier))
                    : localVarIdentifier;
                finallyBlock = finallyBlock.AddStatements(
                    SyntaxFactory.ExpressionStatement(SyntaxFactory.InvocationExpression(
                                                          SyntaxFactory.MemberAccessExpression(
                                                              SyntaxKind.SimpleMemberAccessExpression,
                                                              SyntaxFactory.IdentifierName(marshalerLocalName),
                                                              SyntaxFactory.IdentifierName("CleanUpNativeData")))
                                                      .AddArgumentListArguments(SyntaxFactory.Argument(cleanUpExpression))));
            }

            var args = SyntaxFactory.ArgumentList().AddArguments(
                (from p in innerMethod.ParameterList.Parameters
                 select argsByParameter[p]).ToArray());
            var invocation = SyntaxFactory.InvocationExpression(
                SyntaxFactory.IdentifierName(innerMethod.Identifier),
                args);
            StatementSyntax invocationStatement;
            StatementSyntax returnStatement = null;

            if (innerMethod.ReturnType != null && (innerMethod.ReturnType as PredefinedTypeSyntax)?.Keyword.Kind() != SyntaxKind.VoidKeyword)
            {
                if (marshaledResult.MarshalerType != null)
                {
                    string marshalerLocalName = acquireMarshaler(marshaledResult.MarshalerType);
                    inputMarshaling.Add(
                        SyntaxFactory.LocalDeclarationStatement(
                            SyntaxFactory.VariableDeclaration(IntPtrTypeSyntax)
                            .AddVariables(SyntaxFactory.VariableDeclarator(resultLocal.Identifier)
                                          .WithInitializer(SyntaxFactory.EqualsValueClause(IntPtrZeroExpressionSyntax)))));

                    var intPtrResultExpression = SyntaxFactory.AssignmentExpression(
                        SyntaxKind.SimpleAssignmentExpression,
                        resultLocal,
                        SyntaxFactory.ObjectCreationExpression(
                            IntPtrTypeSyntax,
                            SyntaxFactory.ArgumentList(SyntaxFactory.SingletonSeparatedList(SyntaxFactory.Argument(invocation))),
                            null));
                    var castToManagedExpression = SyntaxFactory.CastExpression(
                        marshaledResult.FriendlyType,
                        SyntaxFactory.InvocationExpression(
                            SyntaxFactory.MemberAccessExpression(
                                SyntaxKind.SimpleMemberAccessExpression,
                                SyntaxFactory.IdentifierName(marshalerLocalName),
                                SyntaxFactory.IdentifierName("MarshalNativeToManaged")),
                            SyntaxFactory.ArgumentList(SyntaxFactory.SingletonSeparatedList(SyntaxFactory.Argument(resultLocal)))));

                    invocationStatement = SyntaxFactory.ExpressionStatement(intPtrResultExpression);
                    returnStatement     = SyntaxFactory.ReturnStatement(castToManagedExpression);

                    finallyBlock = finallyBlock.AddStatements(
                        SyntaxFactory.ExpressionStatement(SyntaxFactory.InvocationExpression(
                                                              SyntaxFactory.MemberAccessExpression(
                                                                  SyntaxKind.SimpleMemberAccessExpression,
                                                                  SyntaxFactory.IdentifierName(marshalerLocalName),
                                                                  SyntaxFactory.IdentifierName("CleanUpNativeData")))
                                                          .AddArgumentListArguments(SyntaxFactory.Argument(resultLocal))));
                }
                else
                {
                    invocationStatement = SyntaxFactory.LocalDeclarationStatement(
                        SyntaxFactory.VariableDeclaration(innerMethod.ReturnType)
                        .AddVariables(SyntaxFactory.VariableDeclarator(resultLocal.Identifier)
                                      .WithInitializer(SyntaxFactory.EqualsValueClause(invocation))));
                    returnStatement = SyntaxFactory.ReturnStatement(resultLocal);
                }
            }
            else
            {
                invocationStatement = SyntaxFactory.ExpressionStatement(invocation);
            }

            var tryBlock = SyntaxFactory.Block()
                           .AddStatements(invocationStatement)
                           .AddStatements(outputMarshaling.ToArray());

            if (returnStatement != null)
            {
                tryBlock = tryBlock
                           .AddStatements(returnStatement);
            }

            body = body
                   .AddStatements(marshalerInitializers.ToArray())
                   .AddStatements(inputMarshaling.ToArray())
                   .AddStatements(SyntaxFactory.TryStatement(tryBlock, SyntaxFactory.List <CatchClauseSyntax>(), SyntaxFactory.FinallyClause(finallyBlock)));

            return(body);
        }
Пример #12
0
 public abstract void WriteMarshalOutputParameter(CppCodeWriter writer, string valueName, MarshaledParameter parameter, IList <MarshaledParameter> parameters, IRuntimeMetadataAccess metadataAccess);
Пример #13
0
 public abstract string WriteMarshalInputParameter(CppCodeWriter writer, MarshaledParameter parameter, IList <MarshaledParameter> parameters, IRuntimeMetadataAccess metadataAccess);
Пример #14
0
 public abstract void WriteMarshalCleanupEmptyParameter(CppCodeWriter writer, string valueName, MarshaledParameter parameter, IRuntimeMetadataAccess metadataAccess);
Пример #15
0
 public override void WriteMarshalCleanupParameter(CppCodeWriter writer, string valueName, MarshaledParameter parameter, IRuntimeMetadataAccess metadataAccess)
 {
 }
Пример #16
0
 public override string WriteMarshalEmptyInputParameter(CppCodeWriter writer, MarshaledParameter parameter, IList <MarshaledParameter> parameters, IRuntimeMetadataAccess metadataAccess)
 {
Пример #17
0
 public abstract bool CanMarshalAsOutputParameter(MarshaledParameter parameter);