Click here to Skip to main content
15,887,485 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I'm linking the library xercesc version 3.2.3 statically into my DLL, but I keep getting linker warnings LNK4286, telling me that the functions and classes I'm using were declared as dllimport, although they're defined within the same binary.

The problem is, obviously, that the xercesc headers are designed for linking this lib dynamically, and any attempt to at least temporarily undefine or redefine the symbols responsible for the dllimport failed.

Is there any reliable way to link xercesc 3.2 statically without linker errors?

P.S.: Since our product is a DLL, we don't want to install third party DLLs on the client system within another application's installation folder. That's why I'm trying to bind it statically.

P.P.S.: adjusted library version: it is actually 3.2.3, not 3.2

P.S. (3): Further investigation showed that
a) the linker warning actually states that the xercesc stuff is declared as dllimport, but shouldn't
b) the macro actually standing in front of these symbols is PARSERS_EXPORT, not any of the other symbols mentioned above.
c) PARSERS_EXPORT is set depending on both DLL_EXPORT and the symbol XERCES_BUILDING_LIBRARY, which doesn't appear to be declared anywhere.
d) unfortunately, my attempts to affect the correct setting of PARSERS_EXPORT by defining XERCES_BUILDING_LIBRARY, while removing the linker warnings, created a lot of other warnings. I'm going to investigate those ... tomorrow

What I have tried:

I've tried it with XERCES_STATIC_LIBRARY, but no matter where I put that #define, it doesn't appear to have any effect.

I've also tried a more subtle approach like including Xerces_autoconf_config.hpp which does most of the defines (and in that process pretty much undoes any of my other attempts to fix the problem), and then re-/undefine DLL_EXPORT and explicitely set XERCES_STATIC_LIBRARY again, but that doesn't seem to work either.

It looks like at least some xercesc headers are implicitely redefining DLL_EXPORT to what is was...
Posted
Updated 17-Dec-20 9:39am
v3
Comments
Rick York 17-Dec-20 12:26pm    
I looked through the source for v3.2.3 and I couldn't find a Xerces_autoconf_config.hpp file. From what I saw, the key was defining DLL_EXPORT or not. Maybe this is something they have fixed in this version of it.
Stefan_Lang 17-Dec-20 14:07pm    
I actually have 3.2.3. The header is in the util subfolder. It does 'hardcode' some #defines (i. e. without checking for any settings, OS or whatnot), and I wonder if that's a bug. Maybe I'll check on previous versions...

P.S.: I just found a comment in the file XercesDefs.h, indicating that the header I mentioned is autoconfigured by the build that created the lib. Also, after double checking on the warning, it seems that the #defines in that file are correct - except that they don't work as intended.
Rick York 17-Dec-20 14:58pm    
Ah - I see it now. It has a .in extension so it didn't show up in searches. I see it has these lines :
#cmakedefine XERCES_DLL_EXPORT 1
#cmakedefine XERCES_STATIC_LIBRARY 1
#define XERCES_PLATFORM_EXPORT @XERCES_PLATFORM_EXPORT@
#define XERCES_PLATFORM_IMPORT @XERCES_PLATFORM_IMPORT@
#define XERCES_TEMPLATE_EXTERN @XERCES_TEMPLATE_EXTERN@
#ifdef XERCES_DLL_EXPORT
# define DLL_EXPORT
#endif

That implies to me that you need to make some changes to that file or change them through cmake somehow.
Stefan_Lang 17-Dec-20 15:09pm    
Apparently the #defines are automatically adjusted based on the build (in this case static lib). Also I misunderstoiod the linker warning, thinking that I need the xercesc stuff to be declared dllimport, when in truth the error is that they are in fact declared as dllimport, but shouldn't. That means the symbols with *EXPOT 1 are in fact correct - it's just that they don't lead to the desired results.

I hve finally found a solution. First of all, the relevant macro symbols controlling the import/export qualifiers for Xercesc version 3.2.3 are the two symbols DLL_EXPORT and XERCES_BUILDING_LIBRARY. Depending on the state of these symbols, the symbol PARSERS_EXPORT is defined (together with several other symbols).

Building Xercesc as a static lib automatically configures the file util/Xerces_autoconf_config.hpp which then defines DLL_EXPORT. The symbol XERCES_BUILDING_LIBRARY however is not defined anywhere: it must be set externally! With both symbols defined, PARSERS_EXPORT will be defined as XERCES_PLATFORM_EXPORT, which in turn is defined as __declspec(dllexport) in the file util/Xerces_autoconf_config.hpp. Which is what we want problem solved.

For me this resolved the linker warnings LNK4286, but it triggered a number of other warnings LNK4248. This is an entirely different issue, but while it doesn't belong here, if anyone else encounters it, check out this link which explains how to resolve it: Linker Tools Warning LNK4248 | Microsoft Docs[^]
 
Share this answer
 
Comments
CPallini 18-Dec-20 9:16am    
So, have my 5.
That means that the library was built as a dll. But you need to rebuild it without the dllimport declarators in order to link it statically.
 
Share this answer
 
Comments
Stefan_Lang 17-Dec-20 14:01pm    
I specifically did build it as a static library, and there is indeed no .dll file. The .lib file is 93967 KB in size - that would be rather unusual for a DLL!

The problem is not with the binary, it is with the include files which insist on treating it as a DLL.
Follow the documentation in order to build it as static library (or libraries?): Build Instructions[^].
 
Share this answer
 
Comments
Stefan_Lang 17-Dec-20 14:13pm    
Thanks, but I did build it as a static lib already. Unfortunately the site you linked does not mention anywhere how to link it to another binary statically. E. g. the symbol XERCES_STATIC_LIBRARY does not seem to be mentioned anywhere on that site - I got that tip from another place. It seems like that symbol is indeed queried, but apparently it isn't quite enough: the #define definitions I've found at least do not query it's state! Which leads me to believe that the logic was changed - and maybe in error.
Richard MacCutchan 18-Dec-20 5:29am    
Quite possibly so, but it should not be too difficult to prevent thos declarators from being defined. I have a library that I can generate as static or dll. The header contains the following at the beginning:
#define	APPLIBRARY_API	// static library use only

#if !defined(APPLIBRARY_API)
  // create DLL
  #if defined(APPLIBRARY_EXPORTS)
    #define APPLIBRARY_API __declspec(dllexport)
  #else
    #define APPLIBRARY_API __declspec(dllimport)
  #endif
#endif

The first #define will generate the library with static linkage. If that is not present then the actual dll generation requires the definition of APPLIBRARY_EXPORTS, which will generate the .lib file. And for users of the dll neither definition being present, the header will label the classes and function as dllimports, which requires the previously generated .lib file for the linker.
Stefan_Lang 18-Dec-20 7:20am    
As I found out the key is XERCES_BUILDING_LIBRARY, which is neither autonatically generated for the static library, nor explained anywhere in the web. As for the latter, I used Duckduckgo to search for it (to avoid all the search manipualtion by Google) and found exactly 7 links. In words: seven. One of them points here, one to a the header file that contains this symbol, 1 to a site that my browser won't open due to a trojan warning and two to sites with asian glyphs, which I opened anyway - but other than posting blocks of code containing the symbol they didn't seem to talk about this particular one. The other two likewise opened to sites with blocks of code, but didn't talk about this symbol.

Basically, the only way to learn about the meaning of this symbol other than reading my solution here is diving into the xercesc header files like I did.
Richard MacCutchan 18-Dec-20 9:15am    
What about help from the owners of the library?
Stefan_Lang 18-Dec-20 10:33am    
Yes, I suppose I could have tried that. But they don't have a forum, just a mailing list, and I was a bit under pressure to find a solution.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900