Exemple #1
0
        private void WriteFunction(CXCursor cursor, string prefixStrip)
        {
            var functionType = clang.getCursorType(cursor);
            var functionName = clang.getCursorSpelling(cursor).ToString();
            var resultType   = clang.getCursorResultType(cursor);

            _tw.WriteLine($@"[DllImport({_libraryVarName}, " +
                          $@"EntryPoint = ""{functionName}"", " +
                          $@"CallingConvention = {functionType.CallingConventionSpelling()}, CharSet = CharSet.Ansi)]");

            if (resultType.IsPtrToConstChar())
            {
                _tw.WriteLine(@"[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(ConstCharPtrMarshaler))]");
            }

            _tw.Write(@"public static extern ");

            FunctionHelper.WriteReturnType(resultType, _tw);

            if (functionName.StartsWith(prefixStrip))
            {
                functionName = functionName.Substring(prefixStrip.Length);
            }

            _tw.Write(@" " + functionName + @"(");

            var numArgTypes = clang.getNumArgTypes(functionType);

            for (uint i = 0; i < numArgTypes; ++i)
            {
                FunctionHelper.WriteArgument(functionType, clang.Cursor_getArgument(cursor, i), _tw, i);
            }

            _tw.WriteLine(@");");
            _tw.WriteLine();
        }
        public CXChildVisitResult Visit(CXCursor cursor, CXCursor parent, IntPtr data)
        {
            if (cursor.IsInSystemHeader())
            {
                return(CXChildVisitResult.CXChildVisit_Continue);
            }

            var cursorKind = clang.getCursorKind(cursor);

            if (cursorKind == CXCursorKind.CXCursor_TypedefDecl)
            {
                var spelling = clang.getCursorSpelling(cursor).ToString();

                if (m_visitedTypeDefs.Contains(spelling))
                {
                    return(CXChildVisitResult.CXChildVisit_Continue);
                }

                m_visitedTypeDefs.Add(spelling);

                var type = clang.getCanonicalType(clang.getTypedefDeclUnderlyingType(cursor));

                // we handle enums and records in struct and enum visitors with forward declarations also
                if (type.kind == CXTypeKind.CXType_Record || type.kind == CXTypeKind.CXType_Enum)
                {
                    return(CXChildVisitResult.CXChildVisit_Continue);
                }

                // no idea what this is? -- template stuff?
                if (type.kind == CXTypeKind.CXType_Unexposed)
                {
                    var canonical = clang.getCanonicalType(type);
                    if (canonical.kind == CXTypeKind.CXType_Unexposed)
                    {
                        return(CXChildVisitResult.CXChildVisit_Continue);
                    }
                }

                if (type.kind == CXTypeKind.CXType_Pointer)
                {
                    var pointee = clang.getPointeeType(type);
                    if (pointee.kind == CXTypeKind.CXType_Record || pointee.kind == CXTypeKind.CXType_Void)
                    {
                        m_tw.WriteLine(@"public partial struct " + spelling);
                        m_tw.WriteLine(@"{");
                        m_tw.WriteLine(@"    public " + spelling + @"(IntPtr pointer)");
                        m_tw.WriteLine(@"    {");
                        m_tw.WriteLine(@"        this.Pointer = pointer;");
                        m_tw.WriteLine(@"    }");
                        m_tw.WriteLine();
                        m_tw.WriteLine(@"    public IntPtr Pointer;");
                        m_tw.WriteLine(@"}");
                        m_tw.WriteLine();

                        return(CXChildVisitResult.CXChildVisit_Continue);
                    }

                    if (pointee.kind == CXTypeKind.CXType_FunctionProto)
                    {
                        m_tw.WriteLine(@"[UnmanagedFunctionPointer(" + pointee.CallingConventionSpelling() + ")]");
                        m_tw.Write(@"public unsafe delegate ");
                        FunctionHelper.WriteReturnType(clang.getResultType(pointee), m_tw);
                        m_tw.Write(@" ");
                        m_tw.Write(spelling);
                        m_tw.Write(@"(");

                        uint argumentCounter = 0;

                        clang.visitChildren(cursor, delegate(CXCursor cxCursor, CXCursor parent1, IntPtr ptr)
                        {
                            if (cxCursor.kind == CXCursorKind.CXCursor_ParmDecl)
                            {
                                FunctionHelper.WriteArgument(pointee, cxCursor, m_tw, argumentCounter++);
                            }

                            return(CXChildVisitResult.CXChildVisit_Continue);
                        }, new CXClientData(IntPtr.Zero));

                        m_tw.WriteLine(@");");
                        m_tw.WriteLine();

                        return(CXChildVisitResult.CXChildVisit_Continue);
                    }
                }

                if (clang.isPODType(type) != 0)
                {
                    var podType = type.ToPlainTypeString();
                    m_tw.WriteLine(@"public partial struct " + spelling);
                    m_tw.WriteLine(@"{");
                    m_tw.WriteLine(@"    public " + spelling + @"(" + podType + @" value)");
                    m_tw.WriteLine(@"    {");
                    m_tw.WriteLine(@"        this.Value = value;");
                    m_tw.WriteLine(@"    }");
                    m_tw.WriteLine();
                    m_tw.WriteLine(@"    public " + type.ToPlainTypeString() + @" Value;");
                    m_tw.WriteLine(@"}");
                    m_tw.WriteLine();
                }

                return(CXChildVisitResult.CXChildVisit_Continue);
            }

            return(CXChildVisitResult.CXChildVisit_Recurse);
        }