Static variables in static lib vs dynamic dll - c++

I'm not too sure of how to ask this, so please comment if I'm being unclear about something.
I have a project which uses a custom class called CManager. Most of my classes in this project inherit from this one and in CManager() (constructor), I add one to the count of CManager object, the count being a static variable in this class. Now, this project used to be compiled as a .dll (dynamic library), but my employer asked me to compile it as a .lib this time, while stripping away a lot of code. Now I have stripped away all the code that wasn't needed and compile it without error... But, when I am creating a .lib, I get an error when I try to execute the program saying that there is an unhandled access violation reading. Here is the code
int CManager::m_count = 0;
CManager::CManager()
{
++m_count; <- Exception here
}
I don't know why I have this error. m_count is a private static int variable declared in the .h.
Since I didn't understand why it wasn't working, I tried compiling the project as a .dll, just so I wouldn'd be doing nothing. And for some reason... it worked. It compiles AND execute (run, wtv).
Now my question is... why is this happening? What explains this?
PS: This project has to include 5 other projects' .lib (or dll), but it work either ways. This project is included by my main, and it is when I try to execute my main that I get the error. The project is just a bunch of algorithms, my main app being the GUI. My main app is an MFC app.
Thanks!
EDIT 1:
While debugging, I found out that if I import the project using a static lib, when passing from my main's function call to the .lib implementation, I loose the object: I call a function on my object, and when I'm in the function, the value of this (refering the object) is null.
If I used a dll, it works perfectly. The object keep its value when a function is called on it.
But I still want to use a .lib, so I don't really know why this happens and how to fix it.

I found it. Like Mark Ransom said in the comments, the problem was not in the code, it was in my project properties. I was creating a .lib instead of dll, but didn't change the runtime library accordingly. So in Project Properties -> C/C++ -> All Options -> Runtime Library, I started using MD and it worked.
Also make sure Runtime Library and general use of MFC are compatible, look here for details.
I'm still not to sure of how using MT created problems, but at least I can run my program now.

Related

How to Debug a COM DLL

I made changes to a function in a COM DLL. I've been unable to figure out how to debug the changes I made.
Background:
I recently inherited a Visual Studio 2012 C++ project that dates back many
years. I'm running Win7 Professional 64-bit.
The top-level design of the project is this:
The code that does most of the work is encapsulated in COM DLLs.
For each DLL there's a separate wrapper function that calls:
(1) CoInitialize
(2) CoCreateInstance
(3) CoUninitialize
There's a main program that presents a dialog to allow a user to select an option. Based on the selected option, the main program calls the appropriate wrapper function, which then runs the code in the corresponding COM DLL.
Problem Details:
(1) I've been unable to step through the code in the Visual Studio debugger.
(Trying to run in the debugger produces the error "Unable to start program
", where the named DLL is different from the modified one.)
(2) I put "fprintf(stderr, ...)" calls in the modified DLL code, but didn't get any output from the "fprintf" calls. (I do see output from "fprintf" calls I added to the wrapper function that invokes the DLL.)
I also tried opening a temporary debug file using "fopen", writing debug statements to the file, then fflush, and fclose. Also no output.
(3) I noticed a post (Calling fprintf from dynamic library (c++)) that suggested that, although "fprintf(stderr, ...)" should work, it would be better to implement a callback to a debug function in the main program. I attempted to do that.
The changes compile, but the linker reports an undefined reference to the name of the function in the DLL that was intended to allow the main program
to pass in a pointer to a callback function.
I'm confused by the undefined reference, because the modified DLL has a different exported function that the linker is able to resolve.
Specifically:
__declspec(dllexport) void SetLogFunc(LogFunc LogFuncPtr) [The new function.]
__declspec(dllexport) BOOL DoRosSum(SRosSumData* pRosSumData) [The existing function.]
I used the "ack" utility to search the entire codebase for the project,
including Visual Studio project files and binary files, looking for
references to "DoRosSum", and can't find any place where there's a reference
to "DoRosSum", but not also a reference to "SetLogFunc".
("SetLogFunc" is listed by "dumpbin" as an exported function.)
I should also mention that I reverted all my changes except for:
the "SetLogFunc" function in the COM DLL,
the callback debug function in the main program, and
the call to ""SetLogFunc"" in the main program.
so I don't think the problem I'm having getting debug output, or running in the VS2012 debugger, is related to the modification I originally made to the DLL code.
Apologies for the long post. In recent years I've mostly been working in C#, or working on linux systems. I have no experience with COM DLLs, so I may be
missing something simple.
If anyone has any thoughts on how to proceed I would appreciate it.
For the first question,
https://learn.microsoft.com/en-us/visualstudio/debugger/how-to-debug-from-a-dll-project?view=vs-2017
I think you can check if you have done this yet. Usually, if you haven't set up command correctly in project property/debugging, running debugger in VC always show you the message:
Unable to start program '......\your DLL'.
Since DLL need to be execute with an executable(.exe).
I noticed that you said the error message 'the named DLL is different from the modified one'.
Your main program will run with multiple DLL right? I think you also need to make sure you put other DLL(.dll) file in the folder of your main program application.
For undefined reference issue,
If you can compile the functions in DLL sides, it means the logic here is ok. However, linker report undefined error then it should be some issues for exporting this function to main program side.
I suppose you to first check in main program side to see if you include the correct header file.
Like right clicking the function name in main program "Go to Definition" will show you the header file. You can then see if the header file is the correct one.
Then you can check if you export functions correctly. You need to make sure main program link to the new compiled Object File Library(.lib). Every time you compile your DLL project you need to make sure main program link to the new compiled .lib and .dll and include the new header file.
Hope these helps.

How to bind static library in a dynamic one in Code::Blocks

I have this static(.a/.lib) library which I wanted to bind in my dynamic(.dll).
Lets say the static library is libColors.a and the dynamic is SWC.dll.
Now I already change the libColors.a project properties to make a static library--build it--and I haven't found any .dll created, only the .o and .a files which is expected. I switched to my SWC.dll project and change its properties to make a dynamic library and check the box to create also a .a file--link the libColors.a--build it--and the .dll file is created. (also note that I put __declspec(import/export) specification on its classes)
Now I want this SWC.dll to use in an executable file. However, when I include only the SWC.h file in the executable, it gets tons of undefined references. Seems there's a problem here since I didn't call any functions on SWC.h. So, I add on my .exe build options the SWC.a, now it builds with no error. But when I run it, it says I needed the Colors.dll? What do I miss?
You can use tools like objdump, CFF Explorer or Dependency Walker to view the import table of the PE-COFF executable in question.
The likely explanation is that the way your Colors project is compiled isn't really a static library. You can check this by inspecting both SWC.dll and your test executable's import table. Chances are that you'll find an import entry from Colors.dll in one of them and what function's it's trying to import.
Check the data and functions declared in Color.h and make sure they're not decorated with __declspec() anywhere. If the functions in Color.h preprocesses into something like __declspec(dllimport) in 'SWC' this can cause the problem you're seeing.

utilizing a static library to create an import library

I am interested in using my static lib to create a dll (implicitly linking). which means I need to (in vs2008)
create a dll project that should generate the following:
header file (which have export function declarations. These are simple wrappers to actual functions in the static lib using __declspec(dllexport) which are in the .cpp )
import lib which will be made as a result of creating the dll
the actual dll which is created.
I have made a test program that will utilize the above dll(including the import lib/header files) to test it.
in this I have included all the three items. now the exe compiles/links without issue.
however in the main.cpp when i call the exported functions (with the associated __declspec(dllimport) call it never seems to execute. I am uncertain why this is?
Its almost like the even though the exe can see the exported function in in the dll...the dll cannot call on the code that is in the static lib?
i just cannot answer why my exe can't see the code in the static lib? do i need an archiver/librarian for vs2008 to include all those obj files as part of the import lib?
I am at a loss and am not sure how to test this?
other than just making my static lib directly into a dll. I wanted to try this method. I know i am missing something...i have read all over the place and i am just stuck. There were some threads here that had some people posting something similar but i can't seem to get it. please be as detailed as possible as I am new to this. thanks again.
update 1:
ok so currently i added the extern line to the function prototype and now it sees the exported function from the dll. however, now the only issue left is that:
i can't invoke the function that this exported function (aka wrapper) is trying to call. which happens to be in the static library. how should my exe get visibility to that static library function. I know it can be done because I think there was one other person on this board who was able to make this work.
update 2: my setup is exactly like this questioner...
How to force inclusion of an object file in a static library when linking into executable?
but i am not using explicit linking. i am using implicit linking. my real issue is how to call a static lib function in my dll wrapper which is exported to the exe?
If the app and DLLs are MFC app/dlls, then make sure that the application and all dlls are either "Debug" versions or "release" versions and not a mix.

VC++ Library Clashing Problem

I am working on a C++ project that uses Qt (gui lib), VTK (graphics lib) and another library which is so obscure I won't mention its name and will instead call it LIB_X. The project uses Qt for the gui components and VTK (more precisely the QVTKWidget extension provided by VTK that supports Qt) for rendering geometry.. and it uses LIB_X to gather and manipulate geometry.
The problem is that it turns out that LIB_X actually uses VTK (where and how, I don't know, it's closed source). At first there was no problem, compiling with both libs linked was going fine, but at some point I called a certain (and highly needed) LIB_X function and compiling led to a bunch of 'blah blah something about a VTK lib/obj already defined in LIB_X dll' errors.
e.g. (and note this is with /FORCE:MULTIPLE so it's a warning here, let me know if you want the error without /FORCE:MULTIPLE and I'll post it):
1>LIB_X.lib(LIB_X.dll) : warning LNK4006: "public: __thiscall std::vector<double,class std::allocator<double> >::~vector<double,class std::allocator<double> >(void)" (??1?$vector#NV?$allocator#N#std###std##QAE#XZ) already defined in vtkCommon.lib(vtkInformationDoubleVectorKey.obj);
I tried using /FORCE:MULTIPLE and it seemed to be a miracle at first, but I am getting random errors in code that would mostly give heap errors. I decided to remove all references to LIB_X from the main project and created a static lib that would handle all LIB_X stuff. I'm not a C++ expert, so I'm not certain how it handles lib clashing when you're using a pre-compiled lib, but I still received lib clashing errors when linking my static lib into my main project, so I still have to use /FORCE:MULTIPLE.
Once I had the static lib it seemed like the random errors had gone away, I was able to do a lot with LIB_X methods in the main project via the static lib, BUT out of nowhere, I added a new data member to my main project's class (a std::vector of doubles) and suddenly I was getting a heap error in one of my static library's methods. If I commented out the new data member, the static library's method would run fine. I hate to give the current error, because honestly I'm not sure if examining it will be worthwhile, but here it is anyway in case it can help:
note: it crashes to xutility on about line 151, pops up assertion:
"file: dbgheap.c line: 1279 expression: _CrtIsValidHeapPointer(pUserData)"
The error comes after adding a vector vector double to a vector vector vector double, crashing on the push_back line:
std::vector<std::vector<double>> tmpVec;
for(srvl_iter = srvl.begin(); srvl_iter != srvl.end(); ++srvl_iter)
{
tmpVec.push_back((*srvl_iter).getControlPoints());
}
this->_splines.push_back(tmpVec); //CRASH
It only started crashing here when I added a new data member to my main project (separate from the static lib!) Commenting out the new data member takes the error away.
std::vector<std::vector<std::vector<double>>> _geometry;
So, /FORCE:MULTIPLE seems bad, I get random errors that just don't make sense to me. Are there other solutions? Am I screwed? Is there something I can do with LIB_X's linking of VTK?
I encountered a bunch of LNK4006 errors when linking my app to a library (call it library LIB_Y) that made heavy use of std::vector<std::string>, which I also did in my app. After a bit of experimenting I found one solution that worked -- wrap LIB_Y in a separate DLL that calls LIB_Y (LIB_Y_WRAPPER, say), and then link the main app against LIB_Y_WRAPPER.
To try out my suggestion you will need to:
Change your "static lib that handles all LIB_X stuff" from a static LIB project into a DLL project (which I will call LIB_X_WRAPPER).
Make sure the header files of LIB_X_WRAPPER don't include any of the LIB_X header files. This is really important because the wrapper needs to completely isolate your app from the data types declared in the LIB_X header files (such as std::vector<double>). Only refer to LIB_X's header files from within the source files of LIB_X_WRAPPER.
Change the declaration of all classes and functions in your static lib to ensure they are exported from the DLL (see this answer if you need details about exporting from a DLL).
This solution worked for me because it kept the instantiation (compiler generated functions) of the std::vector<std::string> class used by LIBY completely separate from the instantiation of std::vector<std::string> in my app.
As an aside, I suspect the cause of the crash you are seeing (you comment it is in the destructor of std::vector<double>) is because the instantiation of std::vector<double> in your app is different to that in LIB_X.
The commenting out is probably just random luck - if you are corrupting the heap you don't always see it right away but an stl vector will allocate and deallocate things left and right so it's no wonder it's finding the error.
Some libs require you include things in a certain order. I am not sure why exactly because to me it seems like giving up and saying you can't design a library properly, but it's the sad fact. So long as you don't include this lib_x anywhere that you include vtk it should be fine, though.
However, they might be fighting over some resource or using something improperly that makes it impossible for them to work together. If you are able to get the compile to work ok by segregating them and it still fails then yes you are just out of luck because it's just a failing in the way that this lib_x was designed and since it's so obscure it's not likely to have been thoroughly debugged against all uses. When something's not widely used it usually ends up being something that works on the developer's machine and project but not necessarily anyone else's.

Trouble compiling dll that accesses another dll

So, I have an interesting issue. I am working with a proprietary set of dlls that I ,obviously, don't have the source for. The goal is to write an intermediate dll that groups together a large series of funnction calls from the proprietary dlls. The problem I am having, when compiling with g++, is that I get errors for the original dlls along the lines of:
cannot export libname_NULL_THUNK_DATA. Symbol not found.
If I add a main and just compile to an executable everything works as expected. I'm using mingw for compilation. Thanks for any help.
In response to the first reply: Either I'm confused about what you're saying or I didn't word my question very well. I'm not explicitly trying to export anything from my wrapper I am just calling functions from their dlls. The problem is that I get errors that it can't export these specific symbols from the dll to my wrapper. The issue is that I'm not even entirely sure what these _NULL_THUNK_DATA symbols are for. I did a search and read somewhere that they shouldn't be exported because they're internal symbols that windows uses. I have tried using the --exclude-symbols directive to the linker but it didn't seem to do anything. I apologize if I'm completely misunderstanding what you're trying to say.
So, I think my issue was related to this. When just compiling a standard executable that uses a dll I was able to include the headers and directly call the functions for example:
#include :3rdparty.h
int main(){
dostuff(); // a function in the 3rdparty.dll
}
this would compile and run fine. I just needed to link the libraries in the g++ command.
When linking with the -shared flag I would get these errors (with main removed of course). I think it has something to do with the fact that by default g++ attempts to import all symbols from the dll. What I didn't understand is why this happens in the dll vs in an executable. I will try doing it using GetProcAddress(). Thank you!
it should be as easy as you think it should be.
eg:
your dll code needs:
void doStuff()
{
3rdparty.login();
3rdparty.dostuff();
3rdparty.logoff();
};
so far - so good, you've included the right headers .... (if you have them, if you don't then you need to import the library using LoadLibrary(), then create a function pointer to each exported dll entrypoint using GetProcAddress() and then call that function pointer)
You then link with the 3rd party lib and that's it. Occasionally you will have to wrap the definitions with 'extern "C"' in order to get the linkage name mangling correct.
As you say you're using g++, you can't be getting confused with __declspec(dllimport) which is a MS VC extension.
"Compiling" tells me that you're approaching this from the wrong end. Your DLL should not export its own wrapper functions, but directly refer to exports from other DLLs.
E.g. in a Windows Kernel32.DEF file, the following forward exists:
EXPORTS
...
HeapAlloc = NTDLL.RtlAllocHeap
There's no code for the HeapAlloc function.