How to PInvoke an Instance Method by disabling Name Mangling
c#, c++, name-mangling, pinvoke
Solution
You cannot disable mangling for a C++ class method, but you may well be able to export the function under a name of your choice using `/EXPORT` or a .def file.
However, your entire approach is brittle because you rely on an implementation detail, namely that `this` is passed as an implicit parameter. And what's more, exporting individual methods of a class is a recipe for pain.
The most sensible strategies for exposing a C++ class to .net languages are:
- Create flat C wrapper functions and p/invoke those.
- Create a C++/CLI mixed mode layer that publishes a managed class that wraps the native class.
Option 2 is preferable in my opinion.
Problem
Given the following c++ class in foo.dll ``` class a{ private: int _answer; public: a(int answer) { _answer = answer; } __declspec(dllexport) int GetAnswer() { return _answer; } } ``` I would like the pInvoke GetAnswer from C#. To do that, I use the following method: ``` [DllImport("foo.dll", CallingConvention = CallingConvention.ThisCall, EntryPoint= "something")] public static extern int GetAnswer(IntPtr thisA); ``` And I pass in an IntPtr that points to an a (that I got from somewhere else, it's not important). `CallingConvention = CallingConvention.ThisCall` makes sure it's handled correctly What's cool about this question is that I know I'm right so far because it's already working great! Using Depends.exe, I can see that "GetAnswer" is exported as ?GetAnswer@a@@UAEHXZ (Or something close - the point being that it's been name mangled). When I plug the mangled name into the "something" for the EntryPoint everything works great! It took me about a day before it dawned on me to use Depends.exe, so I'm going to leave this here as a help to anybody who has a similar issue. My REAL Question is: Is there any way to disable C++ name mangling on GetAnswer so that I don't need to put the mangled name in as my entry point. Having the mangled name in there seems like it could break, because my understanding of name mangling is that it can change if the compiler changes. Also it's a pain in the butt to use Depends.exe for every instance method that I want to pInvoke. Edit: Forgot to add what I've tried: I don't seem to be able to put extern "C" on the function declaration, although I can stick it on the definition. This doesn't seem to help though (which is obvious when you think about it) The only other solution I can think of is a c-style function that wraps the instance method and takes an instance of an a as a parameter. Then, disable name mangling on that wrapper and pInvoke that. I'd rather stick with the solution that I already have, though. I already told my co-workers that pInvoke is great. I'm going to look like an idiot if I have to put special functions in our c++ library just to make pInvoke work.