public FunctionCType FuncType(CType aReturnType, Declaration[] aArgTypes) { var func = new FunctionCType(aReturnType); func.Arguments.AddRange(aArgTypes); return(func); }
public string GenerateRawDelegate(string aIndent, string aFunctionName, FunctionCType aFunctionType) { var assembler = AssembleFunction(aFunctionName, aFunctionType, null, null); if (assembler == null) { return(aIndent + "// Failed to generate: " + aFunctionName); } return(assembler.GenerateNativeDelegateDeclaration(aIndent).Replace("\n", Environment.NewLine)); }
public void AddDeclarations(IEnumerable <Declaration> aDeclarations) { foreach (var decl in aDeclarations) { if (DeclarationsToIgnore.Contains(decl.Name)) { continue; } //== "sp_uint64" || decl.Name == "bool" || decl.Name == "byte") continue; if (decl.Kind == "typedef") { StructCType structType = decl.CType as StructCType; EnumCType enumType = decl.CType as EnumCType; FunctionCType functionType = decl.CType as FunctionCType; if (structType != null) { if (structType.Fields == null) { HandleTable.Add(decl.Name); } else { StructTable.Add(decl.Name, structType); } } else if (enumType != null) { EnumTable.Add(decl.Name, enumType); } else if (functionType != null) { FunctionTypedefTable.Add(decl.Name, functionType); } } else if (decl.Kind == "instance") { FunctionCType funcType = decl.CType as FunctionCType; if (funcType == null) { continue; } FunctionTable.Add(decl.Name, funcType); } } }
string GenerateCSharpWrappingMethod(string aIndent, string aFunctionName, string aHandleName, FunctionCType aFunctionType) { if (!aFunctionName.StartsWith(aHandleName + "_")) { return(aIndent + "// Bad method " + aFunctionName + "\n"); } var methodName = PascalCase(SplitName(aFunctionName.Substring(aHandleName.Length + 1))); var assembler = AssembleFunction(aFunctionName, aFunctionType, aHandleName, methodName); if (assembler == null) { return(aIndent + String.Format("// Skipped function '{0}'.\n", aFunctionName)); } return(assembler.GenerateWrapperMethod(aIndent)); }
IFunctionGenerator AssembleFunction(string aFunctionName, FunctionCType aFunctionType, string aHandleName, string aMethodName) { var enumNames = iEnumNames.ToDictionary(x => x, ManagedNameForNativeType); var structNames = iStructNames.ToDictionary(x => x, ManagedNameForNativeType); var classNames = iHandleNames.ToDictionary(x => x, ManagedNameForNativeType); var delegateNames = iDelegateNames.ToDictionary(x => x, ManagedNameForNativeType); // TODO: Generate transformers once only. // This will require a different approach for ThisPointerArgumentTransformer. var transformers = new List <IArgumentTransformer> { // This-pointer must be handled first to avoid it getting // stolen as a normal handle argument. aHandleName == null ? null : new ThisPointerArgumentTransformer { HandleType = aHandleName }, // C-style empty argument list can go in any order. new VoidArgumentListTransformer(), // These consume multiple arguments. They need to happen // early enough that single-argument mappings don't steal // their arguments. new StringReturnTransformer(), new UnknownLengthStringReturnTransformer(), new StringArgumentTransformer(), new HandleArrayArgumentTransformer(classNames), new TrivialArrayArgumentTransformer(), // Normal arguments. new FunctionPointerArgumentTransformer(delegateNames), new VoidStarArgumentTransformer(), new HandleArgumentTransformer(classNames), // Callback structs get special handling, they need to precede // normal structs which can be passed as ref arguments. new CallbackStructArgumentTransformer(structNames), new RefStructArgumentTransformer(structNames), new ByteArrayArgumentTransformer(), new TrivialArgumentTransformer(enumNames), new RefHandleArgumentTransformer(iStructNames.Concat(iHandleNames)), new RefArgumentTransformer(enumNames), // Pointer-argument comes last because it would match against // other more specific arguments, like handles and ref arguments. new PointerArgumentTransformer(), // Return types. // Error-return has to come first out of the return handlers, // otherwise the error will end up being treated as a regular // enum. new SpotifyErrorReturnTransformer(), new TrivialReturnTransformer(enumNames), new HandleReturnTransformer(classNames), new SimpleStringReturnTransformer(), // Pointer-return must come later than handle-return. new PointerReturnTransformer(), new VoidReturnTransformer() }.Where(x => x != null).ToList(); var assembler = iFunctionFactory.CreateAssembler(aFunctionName, aMethodName); var nativeFunction = iFunctionFactory.CreateAnalyser(aFunctionType.Arguments, aFunctionType.ReturnType); while (nativeFunction.CurrentParameter != null || nativeFunction.ReturnType != null) { var transformer = transformers.FirstOrDefault(x => x.Apply(nativeFunction, assembler)); if (transformer == null) { //Console.WriteLine("/* FAILED AT ARG {0} */", nativeFunction.CurrentParameter != null ? nativeFunction.CurrentParameter.Name : "none"); return(null); } assembler.NextArgument(); } return(assembler); }
public string GenerateDllImportFunction(string aIndent, string aFunctionName, FunctionCType aFunctionType) { var assembler = AssembleFunction(aFunctionName, aFunctionType, null, null); if (assembler == null) { return(aIndent + "// Failed to generate: " + aFunctionName); } string newResult = assembler.GeneratePInvokeDeclaration(aIndent); return(newResult.Replace("\n", Environment.NewLine)); }
public void AddFunction(string aName, FunctionCType aFunction) { NativeFunctions.Add(aName, aFunction); }
string GenerateCSharpWrappingMethod(string aIndent, string aFunctionName, string aHandleName, FunctionCType aFunctionType) { if (!aFunctionName.StartsWith(aHandleName+"_")) { return aIndent + "// Bad method " + aFunctionName + "\n"; } var methodName = PascalCase(SplitName(aFunctionName.Substring(aHandleName.Length+1))); var assembler = AssembleFunction(aFunctionName, aFunctionType, aHandleName, methodName); if (assembler == null) { return aIndent + String.Format("// Skipped function '{0}'.\n", aFunctionName); } return assembler.GenerateWrapperMethod(aIndent); }
IFunctionGenerator AssembleFunction(string aFunctionName, FunctionCType aFunctionType, string aHandleName, string aMethodName) { var enumNames = iEnumNames.ToDictionary(x => x, ManagedNameForNativeType); var structNames = iStructNames.ToDictionary(x => x, ManagedNameForNativeType); var classNames = iHandleNames.ToDictionary(x => x, ManagedNameForNativeType); var delegateNames = iDelegateNames.ToDictionary(x => x, ManagedNameForNativeType); // TODO: Generate transformers once only. // This will require a different approach for ThisPointerArgumentTransformer. var transformers = new List<IArgumentTransformer>{ // This-pointer must be handled first to avoid it getting // stolen as a normal handle argument. aHandleName == null ? null : new ThisPointerArgumentTransformer{HandleType = aHandleName}, // C-style empty argument list can go in any order. new VoidArgumentListTransformer(), // These consume multiple arguments. They need to happen // early enough that single-argument mappings don't steal // their arguments. new StringReturnTransformer(), new UnknownLengthStringReturnTransformer(), new StringArgumentTransformer(), new HandleArrayArgumentTransformer(classNames), new TrivialArrayArgumentTransformer(), // Normal arguments. new FunctionPointerArgumentTransformer(delegateNames), new VoidStarArgumentTransformer(), new HandleArgumentTransformer(classNames), // Callback structs get special handling, they need to precede // normal structs which can be passed as ref arguments. new CallbackStructArgumentTransformer(structNames), new RefStructArgumentTransformer(structNames), new ByteArrayArgumentTransformer(), new TrivialArgumentTransformer(enumNames), new RefHandleArgumentTransformer(iStructNames.Concat(iHandleNames)), new RefArgumentTransformer(enumNames), // Pointer-argument comes last because it would match against // other more specific arguments, like handles and ref arguments. new PointerArgumentTransformer(), // Return types. // Error-return has to come first out of the return handlers, // otherwise the error will end up being treated as a regular // enum. new SpotifyErrorReturnTransformer(), new TrivialReturnTransformer(enumNames), new HandleReturnTransformer(classNames), new SimpleStringReturnTransformer(), // Pointer-return must come later than handle-return. new PointerReturnTransformer(), new VoidReturnTransformer()}.Where(x=>x!=null).ToList(); var assembler = iFunctionFactory.CreateAssembler(aFunctionName, aMethodName); var nativeFunction = iFunctionFactory.CreateAnalyser(aFunctionType.Arguments, aFunctionType.ReturnType); while (nativeFunction.CurrentParameter != null || nativeFunction.ReturnType != null) { var transformer = transformers.FirstOrDefault(x=>x.Apply(nativeFunction, assembler)); if (transformer == null) { //Console.WriteLine("/* FAILED AT ARG {0} */", nativeFunction.CurrentParameter != null ? nativeFunction.CurrentParameter.Name : "none"); return null; } assembler.NextArgument(); } return assembler; }
public string GenerateRawDelegate(string aIndent, string aFunctionName, FunctionCType aFunctionType) { var assembler = AssembleFunction(aFunctionName, aFunctionType, null, null); if (assembler == null) { return aIndent +"// Failed to generate: " + aFunctionName; } return assembler.GenerateNativeDelegateDeclaration(aIndent).Replace("\n", Environment.NewLine); }
public string GenerateDllImportFunction(string aIndent, string aFunctionName, FunctionCType aFunctionType) { var assembler = AssembleFunction(aFunctionName, aFunctionType, null, null); if (assembler == null) { return aIndent +"// Failed to generate: " + aFunctionName; } string newResult = assembler.GeneratePInvokeDeclaration(aIndent); return newResult.Replace("\n", Environment.NewLine); }