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