1

I have a very simple C++ test project that is giving me the error:

   error LNK2001: unresolved external symbol "int __cdecl DnsPluginInitialize(void *,void *)" (?DnsPluginInitialize@@YAHPEAX0@Z)

My header file is like so:

#ifdef DNSPLUGIN_EXPORTS
#define DNSPLUGIN_API __declspec(dllexport)
#else
#define DNSPLUGIN_API __declspec(dllimport)
#endif

DNSPLUGIN_API int DnsPluginInitialize(PVOID, PVOID);

and my cpp file is just this:

#include "stdafx.h"
#include "DnsPlugin.h"


#pragma comment(linker,"/EXPORT:DnsPluginInitialize=?DnsPluginInitialize@@YAHPEAX0@Z")
DNSPLUGIN_API int DnsPluginInitialize(PVOID a1, PVOID a2) { 
    return 0; 
}

I'm very new to C++ and spent a lot of time trying to figure this out myself but just can't get there, as everything online seems to suggest I'm missing an external library... but I'm not using any.

Further info in case it helps:

This is a win32 DLL project in Visual Studio 2010.

The DnsPluginInitialize function needs to be called by an external program and apparently this export signature is correct (I have seen other people using this exact code in their examples)

vbscrub
  • 126
  • 5
  • 3
    Does this answer your question? [What is an undefined reference/unresolved external symbol error and how do I fix it?](https://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix) – Ken White Jan 11 '20 at 01:05
  • 3
    *external symbol* does not necessarily mean an external library. – Ken White Jan 11 '20 at 01:05
  • 1
    Look in the obj file to see how your `DnsPluginInitialize` ended up decorated. Perhaps it's not `__cdecl`. – Raymond Chen Jan 11 '20 at 01:25
  • 1
    Could it be a missing `extern "C" { ... }`? – Ted Lyngmo Jan 11 '20 at 01:25
  • @TedLyngmo using `extern "C"` and getting rid of the pragma linker export did seem to be the key, thanks (although weirdly it works fine even with the pragma export if I change to target x64) – vbscrub Jan 12 '20 at 15:52
  • Great! I've rarely used the pragma export myself, so I don't know how it works really. – Ted Lyngmo Jan 12 '20 at 21:45

1 Answers1

0

So it seems like its an issue with x86 vs x64 differences... which is not something I would have guessed from the error message.

If I change the project to target the x64 platform, it compiles straight away with no errors. But as soon as I change back to Win32, I get that same error about unresolved external symbols.

However, I can get it to compile for Win32 if I just remove the pragma comment export and let __declspec(dllexport) take care of the export. I still end up with DnsPluginInitialize@@YAHPEAX0@Z as the export signature when I look at the file with DumpBin but I guess I can just use extern "C" to avoid that for the 32 bit version. EDIT: Actually can't I just use extern C for both the 32 bit and 64 bit versions? It seems like all the pragma comment export is trying to do is make it so calling the function name on its own will work without having to use the decorated name right?

So for now I'm happy it works, but I'm still pretty curious what causes this. I'm guessing its something to do with __cdecl being ignored on X64 combined with pragma comment /export not being supported for __cdecl. But I don't know enough about C++ yet to really know what's going on. If anyone wants to propose their explanations, I'd be keen to hear them.

vbscrub
  • 126
  • 5