Discussion:
Name decoration and /clr - Linker Error - $$F
(too old to reply)
Martin B.
2010-03-22 12:06:45 UTC
Permalink
Hi all!

We have some issues with unresolved external tokens when
compiling/linking a Mixed C++ Project ( /clr).

Currently we're trying to figure out if the name mangling scheme gets
messed up somehow, but I have a hard time making sense of the
undecorated names we see. I have a little test-setup consisting of a DLL
and and EXE both built with /clr. I get a similar error here.

DLL-Project:
------------
lib.h:
------
#ifdef LIB_EXPORTS
#define LIB_API __declspec(dllexport)
#else
#define LIB_API __declspec(dllimport)
#endif

LIB_API int __cdecl test_fn(void);

lib.cpp:
--------
LIB_API int __cdecl test_fn(void)
{
return 42;
}

EXE-Project:
------------
main.cpp
--------
#include "lib.h"

void f()
{
int ans = test_fn();
}

-----------

The DLL compiles+links without error.

When linking the EXE project I get the following error:
2>main.obj : error LNK2001: unresolved external symbol "int __cdecl
test_fn(void)" (?test_fn@@$$FYAHXZ)

Looking at the generated lib.dll with dependency walker, I see the
following exported symbols:
?test_fn@@YAHXZ


When I disable /clr on the projects, it copiles and links just fine -
the export symbol table for lib.dll show the same function entry.

Any ideas what's going wrong here? What's with that "$$F" ?

cheers,
Martin
Alex Blekhman
2010-03-22 17:50:44 UTC
Permalink
Post by Martin B.
When I disable /clr on the projects, it copiles and links just fine -
the export symbol table for lib.dll show the same function entry.
Any ideas what's going wrong here? What's with that "$$F" ?
I am not sure about this problem, but if you add `extern "C"' for the
exported function the problem may go away because it will suppress C++
name mangling.

Alex
Martin B.
2010-03-23 06:42:10 UTC
Permalink
Post by Alex Blekhman
Post by Martin B.
When I disable /clr on the projects, it copiles and links just fine -
the export symbol table for lib.dll show the same function entry.
Any ideas what's going wrong here? What's with that "$$F" ?
I am not sure about this problem, but if you add `extern "C"' for the
exported function the problem may go away because it will suppress C++
name mangling.
Thanks, but of course this is only a test program. Adding extern C with
the real thing isn't an option because it uses C++ stuff.

Anyone with an idea why or how /clr would have an impact on C++(native)
name mangling and how to workaround it?

(Btw. I forgot to mention: I'm using VS 2005 / VC8)

cheers,
Martin
Martin B.
2010-03-23 11:59:39 UTC
Permalink
Post by Martin B.
Post by Alex Blekhman
Post by Martin B.
When I disable /clr on the projects, it copiles and links just fine -
the export symbol table for lib.dll show the same function entry.
Any ideas what's going wrong here? What's with that "$$F" ?
I am not sure about this problem, but if you add `extern "C"' for the
exported function the problem may go away because it will suppress C++
name mangling.
Thanks, but of course this is only a test program. Adding extern C with
the real thing isn't an option because it uses C++ stuff.
Anyone with an idea why or how /clr would have an impact on C++(native)
name mangling and how to workaround it?
(Btw. I forgot to mention: I'm using VS 2005 / VC8)
I have now found out what our initial problem was.
We used a DLL compiled without /clr that exported a function with the
__fastcall calling convention.
Example:
__declspec(dllexport) int __fastcall test_fn(void);
Resulting export symbol according to dependency walker:
?test_fn@@YIHXZ
( If the function is compiled with:
__cdecl -> ?test_fn@@YAHXZ
__stdcall -> ?test_fn@@YGHXZ
)

Now, if the importing project (be it an executable or another DLL) uses
the /clr switch and links to this DLL the __fastcall attribute will be
ignored (warning C4561) and the following linker error will be generated:
unresolved external symbol: "int __stdcall test_fn(void)"
(?test_fn@@$$FYGHXZ)"

If the function is changed to __stdcall and exported it can be used from
the /clr-compile.

The "$$F" seems to be some additional value generated when linking under
/clr -- it imports the symbol without the $$F just fine if the rest matches.

cheers,
Martin
Tim Roberts
2010-03-25 03:28:36 UTC
Permalink
Post by Martin B.
Thanks, but of course this is only a test program. Adding extern C with
the real thing isn't an option because it uses C++ stuff.
That is completely irrelevant. The only effect of the extern "C" directive
is to change the way the name is decorated when it is exported. It has no
other effect.
--
Tim Roberts, ***@probo.com
Providenza & Boekelheide, Inc.
Loading...