private IEnumerable <StatementSyntax> BuildStringBody(CppFunction cppFunction, TypeInfo returnTypeInfo) { yield return(SyntaxBuilder.DeclareLocals(false)); foreach (var cppParameter in cppFunction.Parameters.Where(p => p.Type.IsConstCharPtr())) { var utf16Name = GetManagedName(cppParameter.Name); var utf8Name = utf16Name + "Utf8"; var ptrName = utf16Name + "Ptr"; yield return(SyntaxBuilder.DeclareSpanForUtf8Variable(utf8Name, utf16Name)); yield return(SyntaxBuilder.DeclarePtrForUtf8Variable(ptrName, utf8Name, utf16Name)); } var call = InvocationExpression(IdentifierName(GetManagedName(cppFunction.Name))) .AddArgumentListArguments(cppFunction.Parameters.Select(BuildArgument).ToArray()); yield return(returnTypeInfo.IsVoid ? (StatementSyntax)ExpressionStatement(call) : (StatementSyntax)ReturnStatement(call)); ArgumentSyntax BuildArgument(CppParameter cppParameter) { var name = GetManagedName(cppParameter.Name); if (cppParameter.Type.IsConstCharPtr()) { name += "Ptr"; } return(Argument(IdentifierName(name))); } }
private IEnumerable <StatementSyntax> BuildBaseMethodBody(CppFunction cppFunction, TypeInfo returnTypeInfo) { yield return(SyntaxBuilder.DeclareLocals(false)); var functionPointer = IdentifierName(GetManagedName(cppFunction.Name + "Ptr")); yield return(SyntaxBuilder.CallGuard(functionPointer)); IdentifierNameSyntax result = null; if (!returnTypeInfo.IsVoid) { if (returnTypeInfo.IsFunction) { yield return(SyntaxBuilder.DeclareResultVariable(SyntaxBuilder.IntPtrName, out result)); } else { yield return(SyntaxBuilder.DeclareResultVariable(returnTypeInfo.TypeSyntax, out result)); } } var delegates = new Dictionary <string, string>(); foreach (var cppParameter in cppFunction.Parameters) { if (TypeMap.TryResolveType(cppParameter.Type, out var typeInfo) && typeInfo.IsFunction) { delegates.Add(cppParameter.Name, null); } yield return(SyntaxBuilder.EmitPush(IdentifierName(GetManagedName(cppParameter.Name)))); } yield return(SyntaxBuilder.EmitPush(functionPointer)); yield return(SyntaxBuilder.EmitCalli(returnTypeInfo, cppFunction, TypeMap, delegates)); if (result != null) { yield return(SyntaxBuilder.EmitPop(result)); if (returnTypeInfo.IsFunction) { yield return(ReturnStatement( InvocationExpression( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, IdentifierName(nameof(Marshal)), GenericName(nameof(Marshal.GetDelegateForFunctionPointer)) .AddTypeArgumentListArguments(returnTypeInfo.TypeSyntax))) .AddArgumentListArguments(Argument(result)))); } else { yield return(ReturnStatement(result)); } } }
private IEnumerable <StatementSyntax> BuildDelegateBody(CppFunction cppFunction, TypeInfo returnTypeInfo) { yield return(SyntaxBuilder.DeclareLocals(false)); var delegates = new Dictionary <string, string>(); foreach (var cppParameter in cppFunction.Parameters) { if (!TypeMap.TryResolveType(cppParameter.Type, out var paramTypeInfo, false)) { throw new ArgumentException(); } if (!paramTypeInfo.IsFunction) { continue; } var managedParameterName = GetManagedName(cppParameter.Name); var variableName = managedParameterName + "Ptr"; delegates.Add(cppParameter.Name, variableName); yield return(SyntaxBuilder.DeclareDelegatePointerVariable(managedParameterName, variableName)); } var call = InvocationExpression(IdentifierName(GetManagedName(cppFunction.Name) + "Private")) .AddArgumentListArguments(cppFunction.Parameters.Select(BuildArgument).ToArray()); if (returnTypeInfo.IsVoid) { yield return(ExpressionStatement(call)); } else { yield return(LocalDeclarationStatement( VariableDeclaration(returnTypeInfo.TypeSyntax) .AddVariables(VariableDeclarator("result").WithInitializer( EqualsValueClause(call))))); } foreach (var cppParameter in cppFunction.Parameters.Reverse()) { if (delegates.ContainsKey(cppParameter.Name)) { var managedParameterName = GetManagedName(cppParameter.Name); yield return(SyntaxBuilder.CallKeepAlive(IdentifierName(managedParameterName))); } } if (!returnTypeInfo.IsVoid) { yield return(ReturnStatement(IdentifierName("result"))); } ArgumentSyntax BuildArgument(CppParameter cppParameter) { var name = delegates.TryGetValue(cppParameter.Name, out string paramName) ? paramName : GetManagedName(cppParameter.Name); return(Argument(IdentifierName(name))); } }