private static string GetName(MethodInfo method, System.Runtime.InteropServices.ComTypes.FUNCKIND funcKind) { var cppNs = GetCppNamespace(method); var methodName = method.Name; // C++ has a lot more overloads than C#, "void f(int*)" and "void f(const int*)". We need // a way to specify that "void g(ref int)" should really call f(). var dllImportAttribute = method.GetCustomAttribute <JDanielSmith.Runtime.InteropServices.DllImportAttribute>(); string entryPoint = dllImportAttribute.EntryPoint; if (!String.IsNullOrWhiteSpace(entryPoint)) { methodName = entryPoint; } if (funcKind == System.Runtime.InteropServices.ComTypes.FUNCKIND.FUNC_NONVIRTUAL) // i.e., "static" method { cppNs = "@" + method.DeclaringType.Name + cppNs; } else if (funcKind == System.Runtime.InteropServices.ComTypes.FUNCKIND.FUNC_VIRTUAL) // i.e., instance method { cppNs = "@" + method.DeclaringType.Name + cppNs; if (IsConst(method)) { int lastIndex_const = methodName.LastIndexOf(@const, StringComparison.Ordinal); bool isConstMethodName = lastIndex_const == (methodName.Length - @const.Length); methodName = isConstMethodName ? methodName.Remove(lastIndex_const, @const.Length) : methodName; } } // foo - name return(methodName + cppNs); }
public string Mangle(MethodInfo method, System.Runtime.InteropServices.ComTypes.FUNCKIND funcKind, CharSet charSet = CharSet.Unicode) { string access = "Y"; // "none" (not public/private/protected static/virtual/thunk) if (funcKind == System.Runtime.InteropServices.ComTypes.FUNCKIND.FUNC_NONVIRTUAL) { access = "S"; // "static" } else if (funcKind == System.Runtime.InteropServices.ComTypes.FUNCKIND.FUNC_VIRTUAL) // i.e., instance method { access = "QE"; // member function, __thiscall, access += IsConst(method) ? "B" : "A"; } var methodParameters_ = method.GetParameters(); // first parameter is "this", don't use it for mangling int skip = funcKind == System.Runtime.InteropServices.ComTypes.FUNCKIND.FUNC_VIRTUAL ? 1 : 0; // i.e., instance method var methodParameters = methodParameters_.Skip(skip); string parameters = String.Empty; foreach (var parameter in methodParameters) { parameters += GetParameter(parameter, charSet); } if (!String.IsNullOrWhiteSpace(parameters)) { parameters += "@"; // end of parameter list } else { parameters = typeToString.AsString(typeof(void)); } var returnType = GetReturn(method.ReturnParameter, charSet); // ? - decorated name // name@ - name fragment // @Z - end return("?" + GetName(method, funcKind) + "@@" + access + returnType + parameters + "Z"); }