DLL linking to static libraries - c++

We have a project which is an executable, which loads DLL files at run time as plugins.
We're trying to make a new plug in which has many library dependencies, and some of those dependencies are the same library but different versions that other plugins link to.
Because the libraries are depended on by different plugins at different versions, I would like to statically link/build any dependencies into the new plugin - that way they can't conflict with the old plugin dependencies. As far as I know, nothing in the dependencies of the plugin need to be exported, they're just used by the plugin.
Is it possible to do this?
I've tried building all the static libs in visual studio as static libraries with the runtime set to Multithreaded DLL with the /MD flag, but when I try to build dynamiclibB.dll, I get linker errors. If I set dynamiclibB to build as a static library, it doesn't have the linker errors.
I haven't tried linking newplugin.dll to the static library version of dynamiclibB yet, but I think I have exactly the same situation, so I see no reason why it would work there where it doesn't one level down.
I don't want to build dynamiclibB as a static library anyway, as it would be good to be able to update newplugin.dll without including dynamiclibB.dll if it hasn't been changed, as in, to decouple the update process. This line of reasoning would suggest that I should have .dlls for everything, but the conflicts of versions is what worries me, I think.
I cannot build the plugins as static libraries as they need to be loaded at run time.
Absolutely everything is being built in release mode for now, to avoid that complication.
What am I missing?
An attempt at a diagram that might help understand the situation:
program.exe
|
________________
| |
oldplugin.dll newplugin.dll
| |
dynamiclibA.dll dynamiclibB.dll
|
_________________________
| | |
staticlibA.lib slibC.lib slibD.lib
Update:
Providing some more information now that I know what's happening, and know that more specific details are actually relevant.
So library A, represented by dynamiclibA and staticlibA was zlib.
The library we were compiling (dynamiclibB) for use in the newplugin was PoDoFo.
The error messages we got were:
Error 19 error LNK2001: unresolved external symbol
_deflateInit_ E:\Work\podofo_bin\src\PdfFiltersPrivate.obj podofo_shared Error 20 error LNK2001: unresolved external symbol
_inflateEnd E:\Work\podofo_bin\src\PdfFiltersPrivate.obj podofo_shared Error 21 error LNK2001: unresolved external symbol
_inflateEnd E:\Work\podofo_bin\src\libpng16.lib(pngread.obj) podofo_shared Error 22 error LNK2001: unresolved external symbol
_deflate E:\Work\podofo_bin\src\PdfFiltersPrivate.obj podofo_shared Error 23 error LNK2001: unresolved external symbol
_deflate E:\Work\podofo_bin\src\libpng16.lib(pngwutil.obj) podofo_shared Error 24 error LNK2001: unresolved external symbol
_deflateEnd E:\Work\podofo_bin\src\PdfFiltersPrivate.obj podofo_shared Error 25 error LNK2001: unresolved external symbol
_deflateEnd E:\Work\podofo_bin\src\libpng16.lib(pngwrite.obj) podofo_shared Error 26 error LNK2001: unresolved external symbol
_inflateInit_ E:\Work\podofo_bin\src\PdfFiltersPrivate.obj podofo_shared Error 27 error LNK2001: unresolved external symbol
_inflateInit_ E:\Work\podofo_bin\src\libpng16.lib(pngrutil.obj) podofo_shared Error 28 error LNK2001: unresolved external symbol
_inflate E:\Work\podofo_bin\src\PdfFiltersPrivate.obj podofo_shared Error 29 error LNK2001: unresolved external symbol
_inflate E:\Work\podofo_bin\src\libpng16.lib(pngrutil.obj) podofo_shared
Putting the rest in an answer.

In my question, slibc.lib was libpng. Libpng also requires zlib, but it builds it from source inside its solution. We were able to use the output of that project in the way we desired, as in, zlib.lib built with /MD flag, without linking errors.
We've also managed to work out why this problem occurred:
another stackoverflow question was very relevant: https://stackoverflow.com/a/6559315/78823
Turns out that zlib has a #define ZLIB_WINAPI which defined the call convention to be STDCALL, which I don't understand, but it caused the linker errors. The other answer suggests to remove the define, and I suppose that's what libpng did with its zlib project.
I'm guessing that the reason why the linker errors only occurred when building the .dll and disappeared when building the .lib is because (correct me if I'm wrong, I don't fully understand this), build a .lib doesn't actually do the linking to the required functions, so would have been just passing on the linker errors to the next level up; I think we would have seen the same errors (but in different objs/projects perhaps) when compiling newplugin.dll, but we didn't get far enough to check that before we tried other things.

Related

Tensorflow config.pb.h causes unresolved external symbols error

I am trying to build the tensorflow C++ API (version 1.15.0, under Windows). I have managed to do so (after manually exporting some functions), but when used in the project I get the linker errors which are caused by the protobuf generated files config.pb.h located in the core include folders within TF.
error LNK2001: unresolved external symbol "const tensorflow::ConfigProto::`vftable'" (??_7ConfigProto#tensorflow##6B#)
error LNK2001: unresolved external symbol "const tensorflow::RunOptions::`vftable'" (??_7RunOptions#tensorflow##6B#)
This can't be resolved by manually adjusting the code before the lib is being built (as far as I know). Am I missing something obvious?

unresolved external symbol inflateEnd (and others) while using boost Zlib

I'm in the process of converting 32bit project to x64. In most cases it just means appending 64 to library paths (and eventually building those libraries for x64). Now I assume all libraries are already ready and the code is also x64 compatible. But I keep getting errors for boost zlib library, like these:
error LNK2019: unresolved external symbol inflateEnd
error LNK2019: unresolved external symbol inflate
error LNK2019: unresolved external symbol inflateInit_
error LNK2019: unresolved external symbol deflateEnd
error LNK2019: unresolved external symbol deflate
error LNK2001: unresolved external symbol "int const boost::iostreams::zlib::default_compression"
error LNK2001: unresolved external symbol "int const boost::iostreams::zlib::deflated"
error LNK2001: unresolved external symbol "int const boost::iostreams::zlib::default_strategy"
I enabled verbose mode for linker (in MS Visual Studio you do this by adding /VERBOSE:LIB to additional linker options). Thanks to that, I can see this output line:
Searching .\..\..\libs\boost145\stage\lib64\libboost_zlib-vc100-mt-gd-1_45.lib
That would imply that the library was found in the boost145\stage\lib64. So what should I be looking for now?
One strange thing is that file that defines the first group of missing symbols (those that are not within boost) has header files within the project, zlib.h and zconf.h. Maybe this is some hint? The zlib.h defines external symbols as:
ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
Obvious question is: where the hell is lib file for this header file?
I had the same issue, to resolve the errors I download the source from zlib and built the x64 dlls/libs locally. There were a couple issues with solution file downloaded, fixes are described below.
Zlib 1.2.8 source code: http://zlib.net/zlib128.zip
Solution File for VS2012 is located at: zlib-1.2.8\contrib\vstudio\vc11\zlibvc.sln
Fixes:
Change:
<Command>cd ..\..\..\contrib\masmx64
bld_ml64.bat</Command>
to:
<Command>cd ..\..\contrib\masmx64
bld_ml64.bat</Command>
In zlibvc project properties -> Linker -> Advanced -> Image Has Safe Exception Handlers -> set to No (/SAFESEH:NO). Info about SAFESEH: Compiling libffi with VS2012 fails with fatal error LNK1281: Unable to generate SAFESEH image

Unresolved External Symbol for definitions with DATA in .def file

I'm trying to use ffmpeg libraries in a VC++ project. I added all the lib files and the headers and set up the properties for the compiler/linker including the .def file for the externals. All the libs/headers/defs come directly from ffmpeg windows 64bit builds. After all that I get errors like:
1>exports.def : error LNK2001: unresolved external symbol pp_help
1>exports.def : error LNK2001: unresolved external symbol swr_ffversion
1>exports.def : error LNK2001: unresolved external symbol sws_context_class
All of the definitions that are failing have a DATA keyword following them.
There are a total of 37 of them and all have the DATA keyword....
I'm new to the VS Compiler/Linker and I might have simply missed something. Any pointers would be greatly appreciated.
Why you define them in exports? You need to use exports.def only when you export something link. For ex. if you develop your own library.
Here you don't need to specify it in exports. You need to correctly link the lib and include headers.
The errors appear, because linker can't find the exported functions definitions. It thinks that you have declared and implemented those functions somewhere.

WMI Linker Error on x64

I'm trying to use the WMI example from msdn:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa384724%28v=vs.85%29.aspx
I've copied the last set of code there verbatim into a console application in VS2008. If I have the application in release or debug for the win32 platform, it compiles (and runs) fine. If I have it in release or debug for the x64 platform, I get the following linker errors:
CppConsole.obj : error LNK2001: unresolved external symbol IID_IWbemConfigureRefresher
CppConsole.obj : error LNK2001: unresolved external symbol CLSID_WbemRefresher
CppConsole.obj : error LNK2001: unresolved external symbol IID_IWbemRefresher
CppConsole.obj : error LNK2001: unresolved external symbol CLSID_WbemLocator
CppConsole.obj : error LNK2001: unresolved external symbol IID_IWbemLocator
fatal error LNK1120: 5 unresolved externals
I've already tried putting the wbemuuid.lib into the linker input directly in the project properties, but that didn't make a difference from the pragma.
Has anybody made this work with x64? Or is there something else I'm doing wrong?
I give credit to RRUZ for this, as he/she at least put me on the right track, but as they haven't posted an answer-answer (just a comment) I can't click them for credit.
Basically, because of the work environment I'm in, the project directories are set up in a "non-standard" way. There was already a copy of wbemuuid.lib in another directory that was not the correct version (not x64), and that directory was higher on the library include list, thus never getting to the right Windows Platform library directory.
So if you ever have problems with x86 vs x64 and library includes, check your directories and check the ORDER of them as well.

Why am I getting error LNK2001 when linking to zlib.lib?

I'm working on a project that already contains the gzip library as follows:
zlib\zlib.h
zlib\zlib.lib
zlib\zconf.h
I would like to use the gzip functions from this .lib but am getting the following errors:
Compress.cpp
Linking...
Compress.obj : error LNK2001: unresolved external symbol _gzclose
Compress.obj : error LNK2001: unresolved external symbol _gzerror
Compress.obj : error LNK2001: unresolved external symbol _gzwrite
Compress.obj : error LNK2001: unresolved external symbol _gzopen
.\Debug/files.exe : fatal error LNK1120: 4 unresolved externals
Error executing link.exe.
The link settings include:
Object/library modules: zlib.lib
Project Options:
zlib.lib
In the file using the gzX() functions, it
#include "zlib/zlib.h"
What else needs to be done here to use these functions?
Thank You.
EDIT: Using Visual Studio 6.0 C++
EDIT2: It turned out the static library I was using had the gz() functions taken out of them. The header file still had them which was misleading.
I grabbed the one off here to get zlib to build in windows. If you did the same, you may have forgotten to #define ZLIB_WINAPI before including zlib.h
you also need to add zlib.lib to your project's libraries:
Project properties->Linker->Input->Additional Dependencies.
When the build stops, ctrl-click on the URL to see the more verbose form of the log and check the actual command line passed to the linker. That at least will tell you whether the option to link against zlib is being respected. You may get other useful diagnostic output. One possibility could be that the architecture is different (eg you're building x64 but the lib is x86)
It turned out the static library I was using had the gz() functions taken out of them. The header file still had them which was misleading.