Question

I'm trying to port Win32::Setupsup, a rather crusty old C++-based module intended to work with Visual C++, to Strawberry Perl and the MinGW GCC that it uses. I've pretty much got it working except for one thing.

The C++ part of the module has a DllMain function that runs some initialization code at DLL_PROCESS_ATTACH and cleanup code at DLL_PROCESS_DETACH. When I compile the module with Visual C++, that works fine. But when I compile it with the MinGW GCC that Strawberry Perl uses, DllMain is never called.

I think the problem is just that DllMain is not properly identified as the DLL's entry point when compiled with gcc. But I don't know how to fix that.

The work-in-progress is in my GitHub repo for Win32::Setupsup. While I use Dist::Zilla to manage releases, you don't actually need dzil to test it. Just clone the repo, perl Makefile.PL, and dmake test.

Was it helpful?

Solution

Looking at your code, you have

BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD reason, LPVOID reserved);

in a C++ source file. Because this is a C++ function, G++ mangles the name to something like __Z7DllMainP11HINSTANCE__mPv@12, and it cannot be found when the library is loaded.

To solve this, use extern "C", either on the function declaration

extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD reason, LPVOID reserved);

or in a block

extern "C" {
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD reason, LPVOID reserved);
}

to ensure that the function is given C linkage (avoiding C++ name mangling).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top