void CSFunctionWriter::WriteManagedFunction(String& source) { JSBClass* klass = function_->GetClass(); JSBPackage* package = klass->GetPackage(); String sig; String returnType = CSTypeHelper::GetManagedTypeString(function_->GetReturnType()); GenManagedFunctionParameters(sig); String line = klass->IsInterface() ? "" : "public "; if (function_->IsStatic()) { line += "static "; } bool marked = false; JSBClass* baseClass = klass->GetBaseClass(); if (baseClass) { JSBFunction* override = baseClass->MatchFunction(function_, true); if (override) { marked = true; if (override->IsVirtual()) line += "override "; else line += "new "; } }
void CSFunctionWriter::WriteManagedPInvokeFunctionSignature(String& source) { JSBClass* klass = function_->GetClass(); JSBPackage* package = klass->GetPackage(); if (klass->IsInterface()) return; source += "\n"; // CoreCLR has pinvoke security demand code commented out, so we do not (currently) need this optimization: // https://github.com/dotnet/coreclr/issues/1605 // line = "[SuppressUnmanagedCodeSecurity]\n"; // source += IndentLine(line); String line = "[DllImport (Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]\n"; source += IndentLine(line); String returnType = CSTypeHelper::GetPInvokeTypeString(function_->GetReturnType()); // handled by out parameter if (function_->GetReturnType() && function_->GetReturnType()->type_->asVectorType()) returnType = "void"; if (returnType == "bool") { // default boolean marshal is 4 byte windows type BOOL and not 1 byte bool // https://blogs.msdn.microsoft.com/jaredpar/2008/10/14/pinvoke-and-bool-or-should-i-say-bool/ source += IndentLine("[return: MarshalAs(UnmanagedType.I1)]\n"); } if (returnType == "string") returnType = "IntPtr"; if (function_->IsConstructor()) returnType = "IntPtr"; const Vector<JSBFunctionType*>& parameters = function_->GetParameters(); Vector<String> args; if (!function_->IsConstructor() && !function_->IsStatic()) { args.Push("IntPtr self"); } if (parameters.Size()) { for (unsigned int i = 0; i < parameters.Size(); i++) { JSBFunctionType* ptype = parameters.At(i); String name = ptype->name_; if (name == "object") name = "_object"; else if (name == "readonly") name = "readOnly"; else if (name == "params") name = "parameters"; // ignore "Context" parameters if (ptype->type_->asClassType()) { JSBClassType* classType = ptype->type_->asClassType(); JSBClass* klass = classType->class_; if (klass->GetName() == "Context") { continue; } if (klass->IsNumberArray()) { args.Push("ref " + klass->GetName() + " " + name); } else { args.Push("IntPtr " + name); } } else { args.Push(CSTypeHelper::GetPInvokeTypeString(ptype) + " " + name); } } } if (function_->GetReturnClass()) { JSBClass* retClass = function_->GetReturnClass(); if (retClass->IsNumberArray()) { args.Push("ref " + retClass->GetName() + " retValue"); } } else if (function_->GetReturnType() && function_->GetReturnType()->type_->asVectorType()) { args.Push("IntPtr returnValue"); } String pstring; pstring.Join(args, ", "); String fname = function_->IsConstructor() ? "Constructor" : function_->GetName(); line = ToString("private static extern %s csb_%s_%s_%s_%u(%s);\n", returnType.CString(), package->GetName().CString(), klass->GetName().CString(), fname.CString(), function_->GetID(), pstring.CString()); source += IndentLine(line); source += "\n"; }