This question might be similar to
DLL Exports: not all my functions are exported
but as it was not fully answered there, I have to ask again. Also my case is because of the use of templates and exporting the whole classes slightly different.
Used environment: VS2008, cl9.0.
I have created a dll-project and added about 40 files (each class a file), mainly headers, because a lot of the classes are templates. An example of the heritage would be:
// Class1.h
template<class TYPE>
class TInt
{
// Some member functions here
// Also a function bool IsValid() const;
};
// Implementation of template here in the header
// Class2.h
#ifndef DllExpImpM
#define DllExpImpM __declspec(dllimport)
#endif
class DllExpImpM CInt : public TInt<double>
{
// Some member functions here
};
// Class2.cpp
// Some includes, including "stdafx.h", which sets DllExpImpM
// to __declspec(dllexport)
template class DllExpImpM TInt<double>;
// Implemenation of CInt
So far, it worked fine as long as I used the debug (compile) option. I was able the use the dll project from other projects.
But if the dll projekt is compiled as release (which works fine), I cannot use it from other projects, because the compiler complains that are some missing functions, e.g. that IsValid() in TInt. I used the dependency walker to check it, and indeed, the compiler is right! The member function IsValid() was not exported, along with another function and with a constructor und the destructor. All other member functions of TInt are exported, I can see them using the dependency walker, I can use them from other projects. This also happens in a similar way with one other class.
I then compared the debug dll and the release dll using the dependency walker and winmerge. They are almost identical, just that the release dll is missing a few functions (about 3 %).
I have no idea what is wrong. I know that I do not have a lot information (the whole information is much too big and I yet could not find a simple example that does not work) and to me all sounds a little bit weird. But perhaps anyone out there once had the same problem. I appreciate every idea very much.
Thank you!
If it works for debug, but not release, then you need to identify what is different. My first guess would be that a #define macro or an equivalent /D macro us not getting defined or is getting defined wrongly.
Maybe DllExpImpM or maybe something else.
If not a macro, then what else changes between builds?
Here are some things I found when I ran into this.
I had the same issue, but taking off the /GL parameter didn't make any difference.
My first test was creating a very simple funcion - void test () - and trying to export it. That didn't work until I got rid of the whole output directory (x64 in my case) and rebuilt it all. It would guess that some intermediate file was messing my compilation, anyway, I didn't investigate it further.
But there was still one function that wouldn't be exported. I took some time to realize the declaration in the .h file wasn't matching exatly the signature in the .cpp file! I was missing a parameter in the .h file... I don't know why it was even compiling, anyway, fixing that allowed the function to be exported.
Related
Let's say I have this lib
//// testlib.h
#pragma once
#include <iostream>
void __declspec(dllexport) test();
int __declspec(dllexport) a();
If I omit the definition for a() and test() from my testlib.cpp, the library still compiles, because the interface [1] is still valid. (If I use them from a client app then they won't link, obviously)
Is there a way I can ensure that when the obj is created (which I gather is the compiler's job) it actually looks for the definitions of the functions that I explicitly exported, and fails if doesn't ?
This is not related to any real world issue. Just curious.
[1] MSVC docs
No, it's not possible.
Partially because a dllexport declaration might legally not even be implemented in the same DLL, let alone library, but be a mere forward declaration for something provided by yet another DLL.
Especially it's impossible to decide on the object level. It's just another forward declaration like any other.
You can dump the exported symbols once the DLL has been linked, but there is no common tool for checking completeness.
Ultimately, you can't do without a client test application which attempts to load all exported interfaces. You can't check that on compile time yet. Even just successfully linking the test application isn't enough, you have to actually run it.
It gets even worse if there are delay-loaded DLLs (and yes, there usually are), because now you can't even check for completeness unless you actually call at least one symbol from each involved DLL.
Tools like Dependency Walker etc. exist for this very reason.
You asked
"Is there a way I can ensure that when the obj is created (which I gather is the compiler's job) it actually looks for the definitions of the functions that I explicitly exported, and fails if doesn't ?"
When you load a DLL then the actual function binding is happenning at runtime(late binding of functions) so it is not possible for the compiler to know if the function definition are available in the DLL or not. Hope this answer to your query.
How do I (programmatically) ensure that a dll contains definitions for all exported functions?
In general, in standard C++11 (read the document n3337 and see this C++ reference), you cannot
Because C++11 does not know about DLL or dynamic linking. It might sometimes make sense to dynamically load code which does not define a function which you pragmatically know will never be called (e.g. an incomplete DLL for drawing shapes, but you happen to know that circles would never be drawn in your particular usage, so the loaded DLL might not define any class Circle related code. In standard C++11, every called function should be defined somewhere (in some other translation unit).
Look also into Qt vision of plugins.
Read Levine's Linkers and loaders book. Notice that on Linux, plugins loaded with dlopen(3) have a different semantics than Windows DLLs. The evil is in the details
In practice, you might consider using some recent variant of the GCC compiler and develop your GCC plugin to check that. This could require several weeks of work.
Alternatively, adapt the Clang static analyzer for your needs. Again, budget several weeks of work.
See also this draft report and think about C++ cross compilers (e.g. compiling on Windows a plugin for a RaspBerry Pi)
Consider also runtime code generation frameworks like asmjit or libgccjit. You might think of generating at runtime the missing stubs or functions (and fill appropriately function pointers with them, or even vtables). C++ exceptions could also be an additional issue.
If your DLL contains calls to the functions, the linker will fail if a definition isn't provided for those functions. It doesn't matter if the calls are never executed, only that they exist.
//// testlib.h
#pragma once
#include <iostream>
#ifndef DLLEXPORT
#define DLLEXPORT(TYPE) TYPE __declspec(dllexport)
#endif
DLLEXPORT(void) test();
DLLEXPORT(int) a();
//// testlib_verify.c
#define DLLEXPORT(TYPE)
void DummyFunc()
{
#include testlib.h
}
This macro-based solution only works for functions with no parameters, but it should be easy to extend.
I am currently working on a project with some old poorly documented code, and am trying to navigate my way through the various .h files that they have provided complete documentation on the use of all of the functions contained (the definitions are held in .lib and .dll files). One of the .h files has functions the are not only declared, but defined with either simple return statements or empty statements as such
class DLL ExampleLibraryClass {
public:
int exampleGetValue() {return 0;}
void exampleSetValue(Type val) {;}
void exampleActionFxn() {;}
};
These would be functions that I expect to return current variable states or perform certain actions, which is why this puzzles me.
Additionally:
I have used Dependency Walker and found that each function does have a matching definition in a dll.
The Keyword DLL has been defined with
#ifndef _PWSDLL_
# define _PWSDLL_
# define WINCALL _stdcall
# ifdef _USRDLL
# define DLL __declspec(dllexport)
# else
# define DLL __declspec(dllimport)
# endif
#endif
_USRDLL is not defined and therefore DLL is defined as __declspec(dllimport)
My question revolves less about the apparent effect of the empty definitions (which do nothing I suppose, and have already been discussed on SO) and more about why the .h file has been written this way and how to utilize the file. Is this a common or known practice? Will the linker still look for definitions to the function in my linked libraries? Are there other pieces of code that I should look for for more clues? Or perhaps in the broadest sense, how should I respond to this?
Many thanks, and please let me know if you need more information to address this, I am unsure what exactly is important in this matter.
EDIT: Added forgotten return types in example code.
EDIT: Added note about DLL definition.
One scenario where you put this code to some use would be to override the functions. These functions hold some default code and could be overridden later.
I'm new to C++ and I'm having a hard time getting my dll references to work. I've been trying to get it to work for a couple of days, but the few explainations I've found often refer to doing x or y, but don't tell me how to do x or y. Since I'm not a C++ veteran, I need someone to walk me through it. What I want to do is the following:
MySolution
MyExe (Win32 .exe)
Main.h
Main.cpp
(constructs ImplementationB calls the methods as defined by InterfaceA, then deletes the instances)
(calls/fills HelperC.Foobar)
MyInterfaces (dll)
InterfaceA.h
~InterfaceA();
virtual void DoSomething();
MyUtils (dll)
HelperC.h
static float Foobar;
HelperD.cpp
float HelperC::Foobar = 1.0f;
MyImplementations (dll)
ImplementationB : InterfaceA
(uses the value from HelperC.Foobar)
The MyExe and MyImplementations projects contain most of the executing code. But, I need an interface, so I need an interface project (MyInterfaces). I need some helper classes that need to be accessible from both MyExe and MyImplementations, hence MyUtils. I would like this helper class to be statically available, though it is not mandatory.
I had a compiling version before I started adding MyUtils with the HelperC class. I had to mark the interface destructor with __declspec(dllexport), along with the DoSomething method. I also had to mark the constructor of ImplementationB in order to instantiate it from MyExe, which makes sense. However, when I tried to mark the entire class (both the implementation and the interface) with __declspec(dllexport), the example wouldn't compile (which does not make sense).
From what I've read, having static fields in a dll and using them from external code doesn't really work all too well. So, as an alternative, I made Foobar non-static and passed a HelperC instance to the method as described by InterfaceA. Since I had already gotten simple classes to work, I figured that should work as well. However, now the compiler is throwing errors on the constructor of ImplementationB (LNK2019).
In short: I'm getting link errors all over the place in sections that have nothing to do with my changes, and there's little documentation describing the specific steps I need to perform in order to get a simple dll reference to work.
Can someone point out what I need to add and where I need to add it in order to make it compile? Also, some do's and don't's about C++ dll references would help a lot (e.g. don't use statics across projects).
After much digging, I found out that the culprit was a magical project setting. It is called Ignore Import Library and is located at Project Properties->Linker->General, and is set to Yes by default, while it should be set to No in most cases. The setting tells the executable project to use the dll's lib file during compilation. This still sounds strange to me (sounds like duplicate build output), but as far as I understand it, the lib file describes how to link to the dll. If your dll produces a lib during build, you probably want to set the setting to No.
I also learned that to be able to use the HelperC class as a statically accessible helper, I needed to use dllimport in combination with the macro trick, as described by #drescherjm. The dllimport declaration is only ever needed to be able to use data members across libraries (static class fields or globally defined variables). It may be applied to functions as well, though it is not required, in which case it provides a slight performance boost during library linking.
For completeness, my project structure after getting it to work:
MySolution
MyExe (Win32 .exe, Debugger Type=Mixed)
Main.h
Main.cpp
(constructs ImplementationB calls the methods as defined by InterfaceA, then deletes the instances)
(calls/fills HelperC::Foobar)
MyInterfaces (dll, Ignore Import Library=Yes, because there is no .lib after building)
InterfaceA.h
class __declspec(dllexport) InterfaceA
~InterfaceA() {};
virtual void DoSomething() = 0;
MyUtils (dll, Ignore Import Library=No)
HelperC.h
class __declspec(dllimport/dllexport) HelperC // (see macro trick)
static float Foobar;
HelperD.cpp
float HelperC::Foobar = 1.0f;
MyImplementations (dll, Ignore Import Library=No)
ImplementationB.h
class __declspec(dllexport) ImplementationB : public InterfaceA
ImplementationB();
~ImplementationB();
void DoSomething();
ImplementationB.cpp
ImplementationB::ImplementationB() {};
ImplementationB::~ImplementationB() {};
ImplementationB::DoSomething() { /* Omitted */ };
(uses HelperC::Foobar in implementation)
On a side note: if you added a default C++ class library project in Visual Studio, you may need to flip the Project Properties->Debugging->Debugger Type setting to Mixed before you will be able to set/use breakpoints in the dll code. See this.
I hope this helps others who are wrestling with dll's in C++ (and Visual Studio).
I have a big C++ Project, in which I try to implement a debug function which needs classes from other libraries. Unfortunately these classes share the same name and namespaces with classes called inside the project. I tried to use a static library to avoid multiple definitions, but of course the compiler complains about that issue. So my question:
It is possible to create that library for the function without that the compiler knows about the called classes inside the function?
I don't know, like a "protected function" or like putting all the code from the libraries inside the function code..
Edit: I'm using the g++ compiler.
Max, I know but so far I see no other way.
Schematic, the problem is.
Project:
#include a.h // (old one)
#include a2.h
return a->something();
return a2->something(); //debug function
debug function a2:
#include a.h // (new one!!)
return a->something(); // (new one!)
Compiling Process looks so far:
g++ project -la -la2
That is a very simplified draft. But that's it actually.
Maybe you can create a wrapper library which internally links to that outside library and exports its definitions under a different name or namespace.
try enclosing the #includes for the declarations of the classes that you are using in your debug function in a namspace, but don't use an using clause for that namespace.
There are a few techniques that may help you, but that depends on what the "debug version" of the library does.
First, it's not unheard of to have #ifdef blocks inside functions that do additional checking depending on whether the program was built in debug mode. The C assert macro behaves this way.
Second, it's possible that the "debug version" does nothing more than log messages. It's easy enough to include the logging code in both debug and release versions, and make the decision to actually log based on some kind of "priority" parameter for each log message.
Third, you may consider using an event-based design where functions can, optionally, take objects as parameters that have certain methods, and then if interesting things happen and the function was passed an event object, the function can call those methods.
Finally, if you're actually interested in what happens at a lower level than the library you're working on, you can simply link to debug versions of those lower level libraries. This is a case of the first option mentioned above, applied to a different library than the one you're actually working on. Microsoft's runtime libraries do this, as do Google's perftools and many "debugging malloc" libraries.
Our project is a VS2008 based project using Boost and Qt heavily. However, today we have a new linking problem that doesn't make any sense.
What is happening is that during the link
For program A, our static library Foobar is finding links to 5 of the 8 member functions.
For program FoobarUnitTest, everything from Foobar links and runs fine.
For program B, our library Foobar2 is a DLL. During the link, it finds all of the member functions except for the constructor and destructor.
When I say the linker finds some of the member functions, what I did was link with /VERBOSE option on. I then went and examined the resulting buildlog.htm file and I could see where the linker was finding some of the functions from the libraries. Linker error is `"error LNK2019: unresolved external"
Also, the same thing happens in 32bit or 64bit - debug or release mode.
Any suggestions as to where to look?
Hard to give any meaningful advice for such a nebulous question but here are a couple things to check out. The linker reports "unresolved externals" when the header says there's a function named "x::y()" but it can't find that function in the lib file. Keep in mind that this assumes you have in fact implemented the functions in question. Ultimately however, whatever the problem ends up being, it will be some morphing of "you told me there's a function named x::y(), but then you didn't implement a functon named x::y()."
So, step zero is make sure you actually have implemented these functions. OK, lets assume you have.
Step 1 is make sure you are declspec(__dllexport)ing the functions in the library's implementation, and declspec(__dllimport)ing the functions on the client side. I use macros for this:
MyFancyLib.h:
#ifndef MYLIB_API
# define MYLIB_API (declspec(__dllimport))
#endif
MYLIB_API void DoIt();
MyFancyLib.CPP:
// this should be moved to stdafx.h or something sufficiently low-level
#define MYLIB_API (declspec(__dllexport))
MYLIB_API void DoIt()
{
// magic happens
}
Step 2: Make sure you've really named things properly in the implementation. One of my most common mistakes is to declare a member function of a class or namespace, say namespace Foo { void DoIt(); };, and then forget to fully-qualify the class or namespace in the implementation. If you never call the function in your implementation, the linker may never look for it.
MyLib.h:
namespace lib
{
MILIB_API void DoIt();
};
MyLib.cpp:
MYLIB_API void DoIt()
{
// magic happens
};
This will generate an unresolved external. The CPP should look like this:
MyLibCorrect.cpp:
MYLIB_API void mylib::DoIt()
{
// magic
}
Step 3: Make sure you're linking to everything you need to link to. This might seem more like step-0 or step-1, but assuming you've linked to everything you think you need, this step can be hard. Look through the names the linker is complaing about, do some undecoration of them and search your library's code for the implementation of those functions. You may find they are exported from a project other than the one you think they're exported from.