Nitin Rawat
Nitin Rawat

Reputation: 209

Mangled name even after extern c

I have included a C++ library in my C# project and i am calling one of it's method.

Earlier I was having the mangling problem then read about extern c and applied it to C++ method.

Then tried calling it like below:

[DllImport(@"F:\bin\APIClient.dll")]
public static extern IntPtr logIn2(IntPtr a, IntPtr b, IntPtr c, IntPtr d, IntPtr e, IntPtr f, int g);

But still I am getting Entry Point exception.

C++:

 APICLIENT_API char* logIn2(const char* a, const char* b,const char* c,const char* d,const char* e,const char* f, int g);

And if i use entryPoint in DLLImport then it works fine:

[DllImport(@"F:\bin\APIClient.dll", EntryPoint = "?logIn2@CAPIClient@API@@QAEPADPBD00000H@Z", CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr logIn2(IntPtr a, IntPtr b, IntPtr c, IntPtr d, IntPtr e, IntPtr f, int g);

Why even after using extern c I have to give this Entry point to make things working.

Upvotes: 0

Views: 865

Answers (1)

Hans Passant
Hans Passant

Reputation: 941635

The decorated C++ name is not a problem. It is actually very desirable, it automatically saves you from having to diagnose a very difficult runtime crash when the C++ code is changed and the function signature is altered. Since there now will be a mismatch and you get an easy "Procedure not found" error message instead of a corrupted call stack that is quite undiagnosable.

The much bigger problem, and the reason that extern "C" doesn't work, is that this is an instance method of the CAPIClient class. It uses the __thiscall calling convention, required to pass a valid this pointer. You can't get that from pinvoke, it requires allocating memory for the C++ object and calling the CAPIClient constructor. Only a C++ compiler knows how to do that correctly, only it knows the correct amount of memory to allocate. So you can't pinvoke, you have to write a C++/CLI wrapper.

The normal mishap when you pinvoke an instance method of a C++ class is a hard crash, typically reported as an AccessViolationException. Triggered when the instance method tries to access another other instance member of the C++ class through the invalid this pointer. Only a static C++ function can be correctly pinvoked. Since you didn't seem to have triggered an exception (yet), there's some hint that the function should have been static in the first place.

Upvotes: 2

Related Questions