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.
Related
I would like to compile a static library out of all the functions I have written for a C++ project. I am using CodeLite 11.0.0 on Ubuntu 16.04, configured to use GCC as compiler.
I have followed the instructions in CodeLite's tutorial, according to which this should be possible, and changed the project type from Executable to Static Library.
After running the project (CTRL+F5 command), I expected to find a .a file in the /Debug folder, either along with, or in place of the executable file. All I could find, though, was the executable and a number of .o and .o.d files. The same I was finding when the project was set to Executable.
I tried to close and reopen CodeLite, but it did not help. I can't find any official/unofficial example of how to build a static library with CodeLite.
Does anyone know how to set-up CodeLite to produce a .a static library file?
As you've probably discovered, CodeLite allows you to change the type of a
project in the drop-down menu from Settings -> General -> Project type.
Doing so, however, does not change the name of the project target. So, if
you started off your project as an executable myprog - from which, say, the
Debug build generated ./Debug/myprog under the project folder - then
you change the project type to static library and rebuild it, the Debug
build will still generate ./Debug/myprog, but that file will now in fact
be a static library, lacking the customary lib-prefix and .a extension.
To give the output file a conventional static library name -
libmyprog.a - you need to go back into Settings -> General and
change Output File from:
$(IntermediateDirectory)/$(ProjectName)
to:
$(IntermediateDirectory)/lib$(ProjectName).a
Then rebuild the project and it will output a target that is a static
library and looks like one.
Of course, you must make the same changes to the project settings in both
the Debug and Release configurations if you want them both to produce
targets with the same file type and file name.
However...
If this way of converting a program project to a static library project does not
seem very slick, that could be because it is a conversion of very little use.
The static library produced after the conversion will contain exactly the same object
files that the program was built from, including the object file that defines
the main function of the original program. Let's suppose that object file
is main.o, and that it defines 0 or more other functions that the linker can see.
Any other program, newprog, that is linked with the static library must provide
its own main function in a different object file, so in any such linkage one of
two things must happen:-
The linkage of newprog does not need any function defined in libmyprog.a(main.o),
so libmyprog.a(main.o) is not linked and might as well not exist.
The linkage of newprog does need some function, foo, defined in libmyprog.a(main.o),
so libmyprog.a(main.o) is linked; then as well as the definition of foo, the
program links duplicate definitions of main - its own definition plus the
one in libmyprog.a(main.o). Duplicate definitions are an error, so the linkage fails.
Putting a definition of some program's main function into a member of a static
library is pointless, because if that member is ever needed in the linkage of another
program then its linkage will fail.
So converting your program project to a static library project calls for some
refactoring prior to the conversion:-
If any function that you want in the static library is defined in the same source
file as main, then you need to take it out of that source file and define it
is a different one.
After that, remove the source file that defines main from the project.
Lastly, convert and rebuild the project.
You have to do that refactoring to extract from your original program source code
a bunch of source files that are suitable for building into a static library.
Assuming you've done that, the straightforward way to create a static library with
CodeLite is to create a project for that purpose and in the New Project Wizard
choose Library -> Static Library as the project type instead of some kind
of executable.
Then just add either new or existing source files to the static library project
until it contains definitions of all the functions you want the library to
provide. Build, test, debug, edit... until done.
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.
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.
I am maintaining a VS2010 project which has a number of cross-referenced COM libraries. I am trying to configure the project in such a way that it is buildable from a random workstation which has VS2010 installed. The workstation could be both 32 and 64 bit, so if I configure project to "register output", the build will fail to build on 32-bit machine, since 64-bit DLL will not be possible to load to call DllRegisterServer.
Here is an example: Typelib from project B references typelib from project A. Project C will reference project B via following statement:
#import "B.tlb"
Since library B references A, when B.tlb is being imported, the compiler tries to load types from A. So, if A is not registered, the compile will fail with:
error C4772: #import referenced a type from a missing type library ...
I tried to open B.tlb using the OleView application, and it's sure as hell only showing right file name for library A reference if it is registered using regsvr32.
So, my question here is: is there any alternative way for library references to resolve themselves properly, without having to register TLBs, just by putting all the files in the same directory somehow, or attaching some sort of manifest? For example, rename the TLB for a library as .tlb or something of that sort.
There is a good option: add path to the .tlb files to VC++ Directories -> Executable Directories
This adds the path to PATH environment variable which will be given to the compiler. According to this: http://msdn.microsoft.com/en-us/library/sce74ah7.aspx all .tlb REFERENCED in imported one are searched only in PATH and LIB.
Try import the referenced A.tlb first, or list it in the import of B.tlb using the include() option.
Only #import the parts of the interface you plan to use if you can avoid bringing in other references unnecessarily.
The easiest way it is place all *.tlb files in dir when they are used.
Depends on your project configuration. Copy all *.tlb files into: $(OutDir), $(ProjectDir), dir where is file with #import, dir when you generate *.tlb etc
Regards,
Mariusz
I am making a static library of my own. I have taken my code which works and now put it into a static library for another program to use. In my library I am using another static library which I don't want the people who will be using my API to know. Since, I want to hide that information from them I can't tell them to install the other static library.
Anyway, I used the command line Lib.exe to extract and create a smaller lib file of just the obj's I used. However, I get a bunch of LNK4006 :second definition ignored linker warnings for each obj I use followed by LNK4221 no public symbols found;archive member will be inaccessible.
I am doing this work in vs2008 and I am not sure what I am doing wrong.
I am using the #pragma comment line in my .cpp file
I have also modified the librarian to add my smaller .lib along with its location.
my code simply makes calls to a couple functions which it should be able to get from those Obj file in the smaller lib.
All my functions are implemented in .cpp file and my header just have the includes of the third party header files and come standard c++ header files. nothing fancy. I have actually no function definitions in there atm. I was going to put the API definition in there and implement that in the .cpp for this static lib that i was going to make. However, I just wanted to build my code before I added more to it.
I did read http://support.microsoft.com/default.aspx?scid=kb;EN-US;815773 but it did not provide a solution.
Even if you extract all objects from the other library and put them in your own library, your users will still be able to see what's in your library and thus see all the object names. In many cases the names of the objects will reveal what's actually the other library you are using.
Instead of distributing your library as a static library, consider distributing it as a DLL. In the DLL you can easily hide all the underlying things and only make public what you want to make public.