I'm working on a cross-platform c++/qt project with a plugin system, we are using so files on linux and dll on windows. We are using gcc on Linux and Visual Studio 2010 on Windows through cmake.
The problem is our plugins sometimes need to call a function from the application source code, which is working fine on Linux with gcc by just including the header files. But on Visual Studio, we got unresolved external symbol errors.
Is it because so and dll files works differently?
thank you.
The default behaviour for exporting symbols from dlls on Windows is exactly opposite: by default, symbols are invisible, you need to export them explicitly. With VC++ this is done by __declspec(dllexport) declarators.
EDIT (Information added): You are entering a region of non-standardized, system specific behaviour... There are much more problems associated with writing cross-platform "pluggable" component systems in C++ than you might be expecting. On Windows there are so called import libraries, which define all symbols exported from a dll. You have to link against these libraries in order to resolve these symbols. This is called implicit linking. You can also link explicitly which means loading dll and its exported symbols at run-time. However all these are just technical details compared to so called binary compatibility issues, which will almost certainly kill you, if not considered during the design of your component system.
I am wondering about one thing: You said you're using Qt. Qt application framework has got it's own cross platform conventions and rules for writing and building pluggable components. Why don't you stick with these...?
Related
Well, trying to build a simple exe in visual studio 2012, with c++ win32 console app, just with a
printf("-----");
After build the release version, its running ok.
When transfer to another windows 7 clean installation, at running i get notice that the MSVCP110.DLL is missing...
Its not a native app ??? why extern dll is needed ?
In old win95 I make many executables with visual C 6 and its run standalone withou any dll.
I will always deplay this dll's with the "native" exe ?
When you write a C++ program, you use a few low-level libraries to interface with the machine. The C++ Standard Library is one example. Consider for example, new. When you call new in your program, you're invoking a piece of code that implements that functionality. Where is that actual code?
It's in a library. That library is deployed in a few different ways. One way is through dynamic linking, where the library is in the form of a DLL that needs to be present on the machine where you run your program. That's what MSVCP110.DLL is -- it's one of the library files your program was compiled against. Another way is to use static linking, where the code from that library is compiled directly in to your program. This results in a signifigant increase in the size of your application, but the other side of that coin is you don't need those library files to be on your target machine. You also need to make sure that other libraries your program use are also built against the same static library. If your program shares data with other programs, you further may need to ensure that those programs use the same static libraries.
Microsoft and Windows aren't unique in this. The same thing happens under Linux, albeit the libraries have different names.
There are pros and cons to using either shared libraries (eg dynamic linking) or static libraries. It's simple and catchy to say "gahrrr I hate shared libraries" but unless you understand why either is appropriate in what situation you stand to deploy a poorly-designed program.
I'm working on a C++ solution in Visual Studio 2010. I've a DLL file which is using some standard C++ library functions (such as string or file functions). For some portability reasons I have to compile this DLL with /MT option, so all required runtime library functions will be linked to the released DLL file.
I've another C++ project which is a windows application, this project also compiles with /MT option and generates an standalone exe file. The second project also uses the same standard C++ library functions that are already linked in my DLL (The executable also uses some DLL exported methods).
Now here is my question: Is there any way to tell linker that don't link common runtime functions which already linked to DLL file & don't link these shared parts again in the exe file (e.g. reuse same code for string functions which already linked to my DLL)?
No, you can't do that. Although executable depends on DLL, they can still be considered as separate and stand-alone binary artifacts, each of which should contain required symbols for proper execution.
This is one of the reasons why dynamic linking is preferred. Furthermore, I don't see any problem to link dynamically and redistribute the runtime with your application.
Although Microsoft Visual C Runtime is included on most platforms, there are many different versions of it, some of which are buggy or/and break backward compatibility. Thus, it is always a good idea to distribute the version of msvcr*.dll that you know works for sure with your application.
I have a C++\MFC application written in Visual Studio 2003 SP1 links to an external static library "SomeExtStaticLib.lib". I also include the header files provided with "SomeExtStaticLib.lib" to create the objects in my application.
SomeExtStaticLib.lib is a static library built with VC6.
Now, I am migrating my application to Visual Studio 2008.
I have very basic question.
Should I also migrate the "SomeExtStaticLib.lib" to VS2008 compiled one?
When I tried to use this VC6 compiled "SomeExtStaticLib.lib" in my VC9 compiled application it did not give any linker errors. I was expecting at least some name mangling issues.
Are static libraries eliminating the name mangling issues?
The issue isn't one of static vs. dynamic linking, nor really of name
mangling. The issue is one of binary compatibility for everything used
in the interface. Thus, for example, unless I'm badly mistaken, the
definition of std::string changed between VC6 and VC9, with a
different layout. So if any of the code uses std::string, you'll have
to recompile, or get strange and unexplicable errors at runtime.
In general, it's best to assume no binary compatibility as soon as
different versions of the compiler, or even different compilation
options are involved, unless the vendor guarantees otherwise. (Although
some common sense is in order: you can freely mix options which only
control warnings, for example. But beware of /Ds which cause added
debugging code to be generated or not.)
If the application is unchanged it needs the same set of symbols from the library. And hence perhaps you can link to the library compiled with VC6.0. Name mangling is not the concern at all unless both the application and library are the same as the compatible(working) ones in VC6.0.
Should I also migrate the SomeExtStaticLib.lib to VS2008 compiled one?
There are compatibility problems between VC6.0 and visual 2008. So YES you should rebuild yor library with Visual 2008.
Just because you can link to the library as is doesn't mean it will work correctly.
Are static libraries eliminating the name mangling issues?
Not really. They are not doing anything special at all.
Static libraries have nothing to do with or without name mangling.... if your code is C++ there is mangling, and if its C (or extern "C" in C++) then there is no mangling. As long as the library and the code that link it agree, there's no problem to link in the library.
I'm developing an application at work using C++, Qt, Mingw32 and Netbeans. I need to use an in house API that has been developed by the software group in the company.
I have the symbol libraries .lib files for the DLLs i need to link against, but i cannot use these libs with Mingw32, it works fine with Microsoft Visual Studio.
Does anyone know if there is a way to export the symbols and create a .a symbol library that works with Mingw32 ? If not i'll have to go over to Visual Studio i guess.
I have tried using the program "pexports" to create a .def file and dlltool, but that didn't work. Still got unreferenced symbol errors, then i added the symbols it complained about to the .def, because they weren't there and it stopped complaining and compiled. But the program crashes. I tried the same code in Visual Studio and it compiles and runs fine.
Have you considered dynamically loading the DLL? LoadLibrary, GetProcAddress, etc. You can probably easily write a class that encapsulates all the DLL's entry points, loading and unloading the library, and does all the #typedefs, etc. It's grunt work but if it's an in-house library there probably aren't too many entry points?
Import libs are overrated. :p
Not sure if it helps, but you may wish to check this guide.
Here's how I did that for the mysql library.
Create a list of exports using dllwrap:
dllwrap --export-all-symbols --output-def libmysql.def libmysql.dll --implib liblibmysql.a
This creates a list of exports in the .def file but the name mangling is incorrect.
Edit the .def file in a text editor and remove the '#' symbols.
The symbol names typically also have a number appended to them as well.
I don't know how to determine the correct name except by experimentation:
Run the following to create a netbeans compatible library:
dlltool --input-def libmySQL.def --dllname libmySQL.dll --output-lib libMySQLclient.a -k
Compile with it and you'll get undefined symbols. The undefined symbols will have the correct decorations.
Edit the .def file again and correct the symbol names. Re-run dlltool to get the correct .a library file.
Have you tried linking the DLL directly, rather than a .a/.lib? MinGW is usually happy to do that for you.
I give up, some people say it is not possible with a dll compiled on microsofts compiler with c++ exports, because of the name mangling
I'm in the process of porting a large C++ application from Linux (gcc) to Windows (Visual C++ 2008) and am having linker issues with plugins. On Linux this wasn't an issue, as .so supports runtime symbol lookup, but dll does not seem to support this.
Some background information:
The application (the host), which hosts a scripting environment, provides interfaces to plugins (shared libraries that are loaded at runtime by script API calls), allowing the host and the scripting API to be extended without recompiling the host application. On Linux this is just a matter of including the host application's headers in the plugin source, but on Windows I'm receiving linker errors. I'm not sure exactly what I need to link with for Visual C++ to resolve these symbols.
One of our dependencies (open source, LGPL) has preprocessor declarations that it uses to insert __declspec(dllexport) and __declspec(dllimport) into it's headers. Some prior research indicates that I may have to do this as well, but I'd like to be sure before I go modifying a whole bunch of core headers. (I was previously able to get this working on MinGW, but we've decided that supporting Visual Studio is a requirement for this sort of commercial project.)
My question, in a nutshell: How do I link runtime-loaded dlls against a host exe in Visual C++?
Edit: To clarify the problem with an example, I have a class in my host application, Object, which represents the base type of an object that may be accessed by a script. In my plugins I have a number of classes which extend Object to perform other functions, such as integrating networking support or new visual elements. This means that my dll must link with symbols in the host exe, and I am not sure how to do that.
What do you mean by "runtime symbol lookup"? Do you mean dynamically loading libraries using dlopen and dlsym and so on? The equivalents in Windows are called LoadLibrary and GetProcAddress.
In windows, you don't export symbols from a executable. You should only export them from a dll. The right way to solve your problem is to rearchitect so that the exported symbols are in a dll that the executable and other plugin dlls can link against.
You can't, easily. The windows loader isn't designed to export symbols out of an EXE and bind them to symbols in a DLL.
One pattern that I have seen is the DLL export a certain function that the EXE calls. It takes as a parameter a structure which contains addresses of functions in the EXE for the DLL to call.
I have been implementing the same, constructing a plugin library to build under both Linux and Windows.
The solution under Linux is to use the -rdynamic option in the gcc command line. This exports all of the symbols in the main executable, so that a plugin can find them on loading.
Under Windows, the solution is to add __declspec(dllexport) in front of the definition of those functions in the exe that you want the dlls to use. Compilation will create a .lib file for the dlls to link to. Certainly works under Visual studio 2008.
Related post: https://stackoverflow.com/a/3756083/1486836
As 1800 INFORMATION says, don't do it like that. Move Object out of the executable and into a "third" DLL. Link the plugins and the executable against that.