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)); }
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)); }
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); } } }
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}"); }
public override bool CanMarshalAsOutputParameter(MarshaledParameter parameter) => base.MarshalInfoWriterFor(parameter).CanMarshalTypeToNative();
protected bool IsInParameter(MarshaledParameter parameter) { TypeReference parameterType = parameter.ParameterType; return((!parameter.IsOut || parameter.IsIn) || (parameterType.IsValueType() && !parameterType.IsByReference)); }
private void WriteMarshalOutputParameter(CppCodeWriter writer, string valueName, MarshaledParameter parameter, IRuntimeMetadataAccess metadataAccess) { if (this.IsOutParameter(parameter)) { this._marshaler.WriteMarshalOutputParameter(writer, valueName, parameter, this._parameters, metadataAccess); } }
public DefaultMarshalInfoWriter MarshalInfoWriterFor(MarshaledParameter parameter) => MarshalDataCollector.MarshalInfoWriterFor(parameter.ParameterType, this._marshalType, parameter.MarshalInfo, this._useUnicodeCharset, false, false, null);
private bool ParameterRequiresCleanup(MarshaledParameter parameter) => (this.IsInParameter(parameter) || parameter.IsOut);
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); }
public abstract void WriteMarshalOutputParameter(CppCodeWriter writer, string valueName, MarshaledParameter parameter, IList <MarshaledParameter> parameters, IRuntimeMetadataAccess metadataAccess);
public abstract string WriteMarshalInputParameter(CppCodeWriter writer, MarshaledParameter parameter, IList <MarshaledParameter> parameters, IRuntimeMetadataAccess metadataAccess);
public abstract void WriteMarshalCleanupEmptyParameter(CppCodeWriter writer, string valueName, MarshaledParameter parameter, IRuntimeMetadataAccess metadataAccess);
public override void WriteMarshalCleanupParameter(CppCodeWriter writer, string valueName, MarshaledParameter parameter, IRuntimeMetadataAccess metadataAccess) { }
public override string WriteMarshalEmptyInputParameter(CppCodeWriter writer, MarshaledParameter parameter, IList <MarshaledParameter> parameters, IRuntimeMetadataAccess metadataAccess) {
public abstract bool CanMarshalAsOutputParameter(MarshaledParameter parameter);