Question

I have created new Win32 project in my VS and have selected Dynamic Library ( *.dll ) for this aim.

I have defined some exporting function in the main file:

__declspec(dllexport)
int TestCall(void)
{
    int value = 4 / 2;
    std::cout << typeid(value).name() << std::endl;
    return value;
}

__declspec(dllexport)
void SwapMe(int *first, int *second)
{
    int tmp = *first;
    *first = *second;
    *second = tmp;
}

When I've looked at the dumpin /exports, I've got:

ordinal hint RVA      name

      1    0 00001010 ?SwapMe@@YAXPEAH0@Z
      2    1 00001270 ?TestCall@@YAHXZ

I'm calling in the C# version like this:

[DllImport(@"lib1.dll", EntryPoint = "?TestCall@@YAHXZ",
CallingConvention = CallingConvention.Cdecl)]
static extern int TestCall();

It's not the correct form of using exported methods. Where did I fail with generating such names for exporting-methods in the C++ dll project?

Was it helpful?

Solution

This is normal, the C++ compiler applies name decoration to functions. The C++ language supports function overloading, much like C# does. So you could write a Foo(int) and a Foo(double) function. Clearly they cannot both be exported as a function named "Foo", the client code wouldn't know which one to call. So the extra characters encode the name so that it is unique for the overload.

You can turn that off by declaring the function extern "C", the C language doesn't support overloading so doesn't require the same kind of decoration.

But it is actually better if you don't. Because it is also an excellent way to catch mistakes. Like changing the function declaration in your C++ code but forgetting to modify the pinvoke declaration in your C# code. You will now get an easy to diagnose "Entrypoint not found" exception instead of a non-descriptive and very hard to diagnose AccessViolationException. Which doesn't necessarily have to be raised in the C++ code, the stack imbalance can also crash your C# code. Looking up the decorated name is a bit painful however, improve that by asking the linker to create a map file (/MAP option).

OTHER TIPS

use extern "C" to specify the linkage to avoid the name mangling:

extern "C" __declspec(dllexport) int TestCall(void);
extern "C" __declspec(dllexport) void SwapMe(int *first, int *second); 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top