Update: I get this warning when compiling: multiple '.text' sections found with different attributes
Hi,
I've compiled some libraries (.a and .dll) in Linux using the MinGW Cross Compiler. I can successfully link against them (.a) in Visual Studio 2008. However, when it runs (using .dll), it terminates with the address pointer pointing at empty memory addresses.
Is there a way/a list of things to do that will allow me to use those libraries successfully in VC08?
The cross compiler generates
*.dll.a
*.dll
Thanks
Found it.
http://www.mingw.org/wiki/MSVC_and_MinGW_DLLs
You have to have a def file and use the VC's lib tool to generate an import library.
It sounds to me like the two parties are not using the same calling convention, meaning there is a problem in the way the exported dll functions have been defined.
By far the simplest approach would be to define the functions as extern "C" by defining the exported functions as follows:
extern "C"
{
int MyExportedFunction(char *buffer, int length);
void MyOtherFunction();
};
Related
I am trying to initialize a static object in a C++ file which is trying to auto register a class to a factory in its constructor (like any standard auto-registration problem). The problem is, this is compiled to a static library, and while linking to an executable, that is optimized away. There should have been a very simple solution to that, but surprisingly, looks like it's not that simple.
Here's my class:
In Factory.h (part of static lib project)
class DummyClass : public BaseFactoryClass
{
int mDummyInt;
public:
DummyClass()
{
std::cout << "Pretending to register myself to the factory here\n";
}
};
In some cpp, let's say Circle.cpp (still part of the static lib project)
static DummyClass dum;
main.cpp (part of the executable)
//some code accessing the BaseFactoryClass of the Registered derived classes.
Now, since the static object is not 'directly' used in the executable project, it's skipped from the linked library.
I want to make it work in MS VC11 (Visual Studio 2012) (and GCC 4.8.*, but that's for later). Looking at other questions, I tried various things so far, which don't seem to work:
Looks like /WHOLEARCHIVE linker option is only supported from Visual
Studio 2015 (We're using VS 2012)
Specifying /OPT:NOREF should have worked (I tried several combination of this with other flags like /OPT:NOICF), but it doesn't work for anyone.
I tried #pragma comment (linker, "/include:symbolName") in the header file, but that gives a linker error about symbol being unrecognized. (And also that wouldn't work in GCC, but probably --whole-archive works there).
There is a flag in Visual Studio Linker Settings that allows linking all object files individually rather than the static lib, but I don't want to go that route. Also, preferably I'd just want to write something in the source (.cpp) of each individual class I want to automatically register, with all the boiler plate code and macros being in a central header like BaseFactory.h etc. Is there any way to do it (even in C++ 11 where there's a guarantee that a symbol will be initialized)? Want to make the registration of a new class as easy as possible for any new developer.
In MSVC you have a linker pragma you can use for that purpose:
#pragma comment (linker, "/export:_dum")
This way whenever the linker is run, it will force link _dum in your executable or DLL.
A better way, though, would be to consider using a DLL instead of a static library. Then you avoid this problem altogether since on each load of the DLL that static variable will be initialized.
I have a .lib static library. I've linked it under the Linker settings 'Additional Library Directories', and 'Additional Dependencies', as well as using pragma comment (lib, "mylib").. And all of that compiles fine.
What I'm asking, and I can only seem to find linking solutions when I look, is how to actually use the functions in it. If I had a function 'MyFunc' referenced in my static library, how could I call it? Visual Studio does not currently recognize any namespaces or functions defined in the library.
Thanks!
You need to get header file for that library, which is usually shipped with the library. After that, you need to include it in your file where you want to use functions from it, and to call functions using declared prototypes.
Your compiler needs to know about prototypes of the functions - because it can't read/parse lib file - that is linker's job.
If I understand what you are asking, you need to declare a prototype for your function-that-lives-in-a-lib:
Say your lib has:
int Foo(int bar) { ... }
In your "consumer" where you pragma your lib in, you'd need something that states:
extern int Foo(int bar);
or even just:
int Foo(int bar);
Usually, you do this via Header files (.h files), and for libraries, they're usually referred to as "include files"
I have some statically compiled libraries (.lib) that I use in my project, which is written in C++ and built on both Windows and Linux. At my project's entry-point to these libraries, I use just one or two functions from the 'main' library in the static library suite, really (but I'm sure that these functions call many others in the other libraries in the suite).
I would ideally like to instead have a suite of dynamically linked libraries (DLLs) that wraps around each of the libs in the static lib suite; I've read/heard that the way to do this on Windows (e.g., Visual Studio 2005/2008/2010) is to "create a wrapper DLL" with some exposed functions calling the underlying static library functions. I would very much appreciate if someone can give me some detailed step-by-step including possibly some snippets, of how to go about doing this in MS Visual Studio 2005/2008/2010. I am sure some of you may already be doing this on a day-to-day basis; your experience is very much appreciated.
Edit:
For the benefit of others like myself, I am posting the first 'useful' link I found:
http://tom-shelton.net/index.php/2008/12/11/creating-a-managed-wrapper-for-a-lib-file/
"Convert a library to another library type" seems easy, but it is not. There is no straight-forward step-by-step way to do this because C++ and DLLs do not play well together at all, and your code will need to be adapted to support a DLL interface.
A concise way to describe the problem is this:
A .lib's interface is C++
A .dll's interface is C
Thus, a DLL's interface simply doesn't support C++ and you need to be clever to make it work - this is why the ambiguous existing answers.
One standard way is via COM, which means building an entire COM wrapper for the library, complete with class factory, interfaces, objects, and using BSTR instead of std::string. I would guess is not practical.
Another solution is to create a C interface for your C++ library which is DLL-safe. That means basically creating a winapi-style interface, which again is probably not practical or defeats the purpose of using your library at all. This is what #David Heffernan suggests. But what he doesn't address is how you must change your code to be DLL-compatible.
An important but subtle problem is you cannot pass ANY templated C++ objects across DLL boundaries. This means passing std::string in or out of a DLL function is considered unsafe. Each binary gets its own copy of the std::string code, and there's no guarantee that they will happen to play nicely with each other. Each binary (potentially) also gets its own copy of the CRT and you will mess up internal state of one module by manipulating objects from another.
Edit: You can export C++ objects in MSVC using __declspec(dllexport) and importing them using __declspec(dllimport). But there are a lot of restrictions on this and subtleties that cause problems. Basically this is a shortcut for getting the compiler to create a cheap C-style interface for your exported class or function. The problem is it doesn't warn you about how much unsafe stuff is happening. To reiterate:
If there are ANY templated symbols crossing DLL bounds, it is not safe (std::* for example).
Any objects with CRT-managed state should not cross DLL bounds (FILE* for example).
If you do not care about interface adaptation at all, you can export symbols from a static .lib to a .dll fairly easily. The trick is, you do not use Visual Studio GUI or projects at all, but just the linker (link.exe).
With this method, C symbols will remain C symbols and C++ symbols will remain C++ symbols. If you need to change that, you need to write wrapper code (e.g. extern C interfaces). This method simply presents existing symbols from the .objs in the .lib as official exports from the DLL.
Assume we have a .lib compiled from a source TestLib.c
#include <stdio.h>
void print(char* str)
{
printf("%s\n", str);
}
int add(int a, int b)
{
return a + b;
}
We compiled this into a static lib TestLib.lib. Now we wish to convert TestLib.lib to TestLibDll.dll (the base name should not be the same or you will get issues with the link output since the linker also creates DLL link .lib). To do this, we use link.exe outside Visual Studio GUI. Launch the "x64 Native Tools Command Prompt for Visual Studio xx" to get a cmd with the toolchain in path. (If you need 32 bit version, use x86 Native Tools instead). Change to the folder with TestLib.lib (e.g x64\Release). Then run:
link /DLL /EXPORT:add /EXPORT:print /OUT:TestLibDll.dll TestLib.lib
This should produce TestLibDll.dll. (The linker may complain a bit about there being no .obj, but you can ignore this.) The exports are:
dumpbin /exports TestLibDll.dll
Microsoft (R) COFF/PE Dumper Version 14.29.30040.0
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file TestLibDll.dll
File Type: DLL
Section contains the following exports for TestLibDll.dll
00000000 characteristics
FFFFFFFF time date stamp
0.00 version
1 ordinal base
2 number of functions
2 number of names
ordinal hint RVA name
1 0 00001080 add
2 1 00001070 print
We have successfully exported the functions.
In the case there are many functions, using /EXPORT is tedious. Instead make a .def file. For our example, here is TestLibDll.def:
LIBRARY TestLibDll
EXPORTS
print #1
add #2
The linker is then run as
link /DLL /DEF:TestLibDll.def /OUT:TestLibDll.dll TestLib.lib
This example uses x64 C symbols, which makes it straightforward. If you have C++ symbols, you need to provide the mangled version of the symbol in the /EXPORT argument or in the def file. For more complex situations than a single static lib, you may need to provide more link libraries on the command line and/or /LIBPATH args to point to link library folders.
Again, this method is only for exporting symbols verbatim from a static library. I personally used it to create a DLL to be loaded in Python with ctypes for a closed source static library. The advantage is you don't need to write any wrapper code or create any additional VS projects at all.
Note: the accepted answer provides a good discussion of pitfalls regarding C++ DLL interface and why C wrappers are a good idea. I did not focus on that here, only on the mechanics of getting the symbols to be exported to the DLL. Using a C interface to DLL if possible remains good advice.
This was a little big to add as a comment to tenfour's response...
If you want to still maintain a C++ API when using the DLL wrapper, you can put C++ to C conversion functions in the header file. This ensures that only C compatible data types ever cross the DLL boundary.
As an example
//MyDLL.h
class MyDLL {
public:
...
int Add2ToValues(std::vector<int>& someValues) {
int* cValues = new int[someValues.size()];
memcpy(cValues, &someValues[0], someValues.size() * sizeof(int));
int retVal = Add2ToValues_Internal(cValues, someValues.size());
someValues.assign(std::begin(cValues), std::end(cValues));
delete [] cValues;
return retVal;
}
private:
int Add2ToValues_Internal(int* valuesOut, const int numValues);
};
//MyDLL.cpp
int MyDLL::Add2ToValues_Internal(int* values, const int numValues)
{
for(int i = 0; i < numValues; ++i) {
values[i] += 2;
}
return 0;
}
One catch I ran into when doing these wrappers is that you must allocate and deallocate any memory within the header file. Since the header file will be compiled by the application that is using your library, it will use the CRT for whatever compiler you are using to build your application. All interaction with the DLL uses C, so you won't run into any runtime mismatches and all memory is allocated and freed either entirely within the DLL or entirely within the application so you don't have any cross DLL memory management issues either. In the example, I both allocated and deallocated in the header. If you need to allocate data in the _Internal function, you'll need to also add a function that allows you to free that memory within the DLL. Once inside of the _Internal functions, you are free to use as much C++ as you want.
I build an application in Borland C++ 6 and I'd like to import external, non Borland library (FFTW, to be exact, http://www.fftw.org).
I have downloaded the fftw dll file, used the implib.exe program to build a lib file known to Borland, included fftw.h in source and copied fftw.h to Borland/include, fftw.lib to Borland/lib and .h, .dll and .lib files to my project folder.
Unfortunately I get several linker errors, which claims:
Unresolved external '{name of the FFTW function}' referenced from {name of the source file}
What do I do wrong?
I'm just telling from a similar story how I managed to get it to work...
There was a DLL that worked (was being sucessfully imported) with Delphi 7, VB.NET and Java. I wanted to make a program with Borland C++ Builder 6 with it. I had the function prototypes and the exact declarations that made the import on those languages. Reasonable?
I thought it would be easy, but I stucked on many dead ends without sucess, with step by step "blind" guides that didn't worked for me. And the IDE or command outputs not helping either.
After a few days I tried (from question 4599357, although the DLL isn't in Visual C++):
using "implib" without "-a" and
having the prototypes declared like this:
extern "C" __declspec(dllimport) __stdcall int someDll_someFunction(someTypes someArgs, ...);
Note that the normal function prototype is at the end. If you have the "normal" prototypes, just add "extern "C" __declspec(dllimport) __stdcall" before them to your source code or header file. :) And I only have functions that return "int", this is why I put "int" there.
I think you're only missing one step... add the .lib file that implib created to your project.
Are you sure that Borland is doing proper name-mangling of the external functions, and that the header has been surrounded with extern "c" {}? And are you sure that Borland is indeed trying to link with the .lib file? Make sure the compiler has the verbose option set.
If that doesn't work, why don't you build FFTW from source instead of using a 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.