views:

379

answers:

6

Hi All.

I've a VS2008 native C++ project, that I wish to compile as a DLL.

It only references one external library (log4cplus.lib), and uses its functions. (also uses log4cplus's .h files , naturally).

When I try to compile my project as a static library, it succeeeds. When I try as DLL, it fails :

1>MessageWriter.obj : error LNK2019: unresolved external symbol "public: static class log4cplus::Logger __cdecl log4cplus::Logger::getInstance(class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > const &)" (?getInstance@Logger@log4cplus@@SA?AV12@ABV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@@Z) referenced in function "class log4cplus::Logger __cdecl Log(void)" (?Log@@YA?AVLogger@log4cplus@@XZ)

There are 4 more errors just like this related to functions within log4cplus.lib.

It seems like something really stupid.. please help me :)

Thanks!

Edit :

I am linked against the log4cplus.lib file, and it finds it just fine. also, the log4cplus.lib is 100% functional, I am using it in another project with no problems. My original intention was to compile my project as a static library and use it in another DLL I am writing, but when do this, I get the same linker errors in that other project...

Edit #2 :

The functions which cause the linker errors are static functions.. could this be part of the problem?

+1  A: 

Are you actually linking with the log2cplus.lib file? If you were compiling as a static library then you would link to it via the final .exe and not in the static library - perhaps that is the difference?

trojanfoe
yes, I am linking with the log4cplus.lib file...
Roey
OK cool - and it's in the library path?
trojanfoe
yes, it finds the file for sure (when I change the lib name to something bogus compilation fails right away)...I don't understand why it doesn't find these functions inside the log4cplus.lib... :(
Roey
Please explain again what you meant in your answer...If I compiled this project as a static lib - then I shouldn't link against log4cplus.lib?I would link against log4cplus.lib only in the .exe project where I use my static lib?
Roey
No, the DLL should link against the log4cplus.lib, which as you say it is - I am stumped as to why it cannot find the symbols. When your project was a static library did you actually link a final .exe to test everything worked?
trojanfoe
The functions that produce the linker errors are static functions..could this be the problem?
Roey
Static class functions or static C functions? If the latter then that would explain it, however I cannot see how the original static library could see those functions either.
trojanfoe
+2  A: 

When you're creating a static library, the library creator does not try to resolve all the functions that you are using (the ones that are in log2cplus.lib). These functions are resolved when you create an executable that links with your static library.

When you're creating a dynamic library, the library creator (the linker) does try to resolve all the functions you are using. You have to provide the linker with the log4cplus.lib library as soon as you build the dynamic library. You cannot wait until you create the executable.

Didier Trosset
I have provided it with the log4cplus.lib.... I've added it to the "linker" portion of the project properties...
Roey
It finds the file for sure... as I have stated below... it just doesn't recognize some functions in it for some reason...
Roey
A: 

Did you use __declspec(dllimport) and __declspec(dllexport)?

They are not necessary when linking static libraries, but required for DLLs. The function has to be declared for exporting (in the DLL), so users can use it outside (and thus import it from the DLL).

Maybe this can help:

Importing into an Application Using __declspec(dllimport)

http://msdn.microsoft.com/en-us/library/8fskxacy%28VS.80%29.aspx

best regards

A: 

If you're using a compiler like MSVC, then it may have changed the project settings without you knowing about it when changing from lib to dll. You should double-check that in DLL mode, you are properly linked to the lib.

DeadMG
+2  A: 

In either case you need to link against library.

Difference is that when you link statically - all functionality is linked via library you're using.

When you're linking dynamically you link against import library which have functionality to load and use functions from dll and this step you're missing. Usually import library have the same name as the dll you're linking against.

Edit:

I saw it that missing symbol is not '__imp...' This means that header file is not "configured" for dynamic linkage, probably because you have LOG4CPLUS_BUILD_DLL or log4cplus_EXPORTS or DLL_EXPORT not defined in project where you include Log4Cplus headers.

XAder
Where should I place the DLL?
Roey
Shouldn't the DLL be loaded only in runtime? why would the linker be trying to find it?
Roey
Right, but you need some information what dll and how to access it, for it there are import libraries. I Think I know what is wrong - see my update.
XAder
I don't understand, should I add this expression to my code? where should I put it?I searched for it and could not find it in my entire project...
Roey
In other way:how you differ from case when you use log4cplus in static or dynamic way - after it it will be easier to see what is done wrong.?
XAder
I didn't know there was any difference,I just link to the .lib file, and #include the header files in my project. I place the log4cplus DLL where I use my DLL.What else needs to be done?
Roey
In this particular case I think you should add log4cplus_EXPORTS define to your project. Although I've never used this library so I'm not 100% sure. Additionally when I've built it on my PC I saw that there's difference between static and dynamic build (name of the library changes from log4cplusS.lib to log4cplus.lib), so probably you changed name manually.
XAder
A: 

There are two possibilities that I can see for the linker error:

  1. You have compiled the log4cplus.dll (and the associated log4cplus.lib import library) using the provided Release build configuration but now your application is compiled with "Character Set" option set to "Use Unicode Character Set"

  2. Or you are trying to use log4cplus' static library but defining LOG4CPLUS_BUILD_DLL for your application.

I bet on number 1. It could be something else, still. What version of log4cplus are you using?

If you want to use log4cplus.dll in your application, define the LOG4CPLUS_BUILD_DLL symbol. log4cplus_EXPORTS and DLL_EXPORT are there only to support the CMake based build system, and autotools based build system on MingGW respectively.

wilx