I have a Visual Studio 2008 solution creating a DLL. It includes a static library. I learned that an exported "__declspec( dllexport )" function in the static library isn't exposed via the DLL. My current workaround is a definition file. What I'm wondering is since only the declaration needs the export why can't I have a header in the DLL project with the following:
__declspec( dllexport ) function();
and in a source file of the static library
__declspec( dllexport ) function() { ...contents... }
When the static library is pulled into the DLL shouldn't the definition be resolved with the declaration and the declaration cause the function to be exported?
I tried adding extern to the declaration as well.
The problem is that the linker, when building the DLL, will notice that nothing in the DLL calls the function and won't include it in the DLL. The fact that you're marking it for export doesn't affect the linker's decision.
The usual workaround is to define another function in the same source file as the exported function, and call that function from elsewhere in the same module (eg. DllMain). That will ensure that the linker includes the module that defines your exported function.
Raymond Chen has a piece about this on his blog.
Related
The following is my scenario:
I have an executable along with multiple shared libraries(.dll or .so). Both the executable and the shared libraries(.dll or .so) uses a set of common libraries. Since they are common libraries I want to reduce the binary foot print of the shared libraries, in order to reduce the shared library's foot print I am exporting the contents of the common libraries from the executable and importing them in shared libraries(dll or .so).
Note: Though size of the foot print is not the only one among multiple reasons, for the time being we can stick with it being major reason.
Problem:
In the common libraries there are some inlined functions and some template classes. When I compile the executable and the shared libraries using performance optimization flags the inlined/ template classes are inlined both in executable and shared libraries. It will create problems if the inline definitions are modified and there are some shared libraries with different set of inline function definitions.
How to solve this problem ?
When I started thinking about this even the STL classes provided by the CRT are template classes. The similar problem exists even in their case. Have they solved this problem? What will happen if they modify the definition of std::vector ? Please help.
A class template is a mechanism for creating class. But these classed don't get instantiated until you define a particular instance of a class (with a template parameter.)
In your export control file.
#ifdef XXXX_BUILD
#define XXXX_EXPORT __declspec(dllexport)
#define XXXX_EXTERN
#else
#define XXXX_EXPORT __declspec(dllimport)
#define XXXX_EXTERN extern
#endif
where XXXX_BUILD is a symbol defined in your project.
To get your class exported.
XXXX_EXTERN template class XXXX_EXPORT YourClass<double>;
Where double is the type you want to instantiate the class with.
https://support.microsoft.com/en-us/help/168958/how-to-export-an-instantiation-of-a-standard-template-library-stl-clas
I'm writing a CLR wrapper for an unmanaged C++ library.
There are two files I'm including from the unmanaged lib:
//MyCLIWrapper.h
#include "C:\PATH\TO\UNMANAGED\Header.h"
#include "C:\PATH\TO\UNMANAGED\Body.cpp"
Then I'm writing CLI implementations for the unmanaged library functions:
//MyCLIWrapper.h
// includes ...
void MyCLIWrapper::ManagedFunction()
{
UnmanagedFunction(); // this function is called successfuly
}
However, if my Unmanaged function contains calls to other functions that are defined in other unmanaged header files. This causes a compiler linkage error.
If I add includes to the unmanaged headers that define these functions, my errors get resolved. However, there is a lot of functions, and a lot of includes required.
Is there a different way to approach this?
EDIT:
P.S.
My managed code is in a separate Visual Studio project (output - DLL), and the compile settings are set to /CLR. Unmanaged code is in a separate Win32 project (output - DLL).
Also, after more research I concluded that theoretically I could set my Win32 unmanaged project to CLR and just add my managed classes and headers in there as an entry point, and then it would all compile into a single DLL file. That would probably solve (?) the linkage errors. However, I would prefer to preserve the loose coupling as well as the additional series of problems that can raise from setting my unmanaged project to CLR.
EDIT #2:
The unmanaged class that I'm referencing (body.cpp, header.h) contains includes to the required files that define the functions that are causing the problems. However, my managed code doesn't pick up on the includes that are in the unmanaged body.cpp and header.h.
Linker errors are a different kettle of fish from compiler errors. You forgot to document the exact linker errors you see, but a very common mishap when you compile code with /clr in effect is that the default calling convention for non-C++ member function changes. The default is __clrcall, a convention that's optimized for managed code. While functions compiled without /clr defaults to __cdecl. Which changes the way the function name is mangled. You see this back in the linker error message, is shows that it is looking for a __clrcall function and can't find it.
You'll need to either explicitly declare your functions in the .h file with __cdecl. Or tell the compiler that these functions are not managed code. Which is the best way to tackle it:
#pragma managed(push, off)
#include "unmanagedHeader.h"
#pragma managed(pop)
Solution was fairly simple:
I added both unmanaged and managed projects to a single solution in Visual Studio.
Set the unmanaged project's "Configuration Type" to "Static Library" (.lib).
Right click on the managed project -> References -> Add Reference -> Projects -> -> Add Reference.
Then in my managed class, I include the header.h (only) just like I did in my question.
Compiled successfully!
Thank you
I have the following static function:
static inline HandVal
StdDeck_StdRules_EVAL_N( StdDeck_CardMask cards, int n_cards )
Can I export this function in a DLL? If so, how?
Thanks,
Mike
Background information:
I'm doing this because the original source code came with a VS project designed to compile as a static (.lib) library. In order to use ctypes/Python, I'm converting the project to a DLL.
I started a VS project as a DLL and imported the original source code. The project builds into a DLL, but none of the functions (including functions such as the one listed above) are exported (as confirmed by both the absence of dllexport in the source code and tools such as DLL Export Viewer). I tried to follow the general advice here (create an exportable wrapper function within the header) to no avail...functions still don't appear to be exported.
You may not export that function from a DLL. static functions are equivalent to private to that file.
You can create a method in the file that calls it and export that.
By defining a function with static and inline you are effectively guaranteeing that it will be only in the modules that includes the definition.
Either edit each file to remove the static inline (which might break) or change everything to use a PreProcessor directive that will allow you to have either:
#define MYAPI static inline
or
#define MYAPI __declspec(dllexport)
and then
MYAPI HandVal StdDeck_StdRules_EVAL_N( StdDeck_CardMask cards, int n_cards )
or build a set of wrappers as a seperate module which does
__declspec(dllexport) HandVal Public_StdDeck_StdRules_EVAL_N( StdDeck_CardMask cards, int n_cards )
{
return StdDeck_StdRules_EVAL_N(cards, n_cards);
}
As Romain said, a static function is private to the file and you can't export it.
You can try:
export the entire class
try make the static method a static inline method.
The compiler is free to inline such a function at the call sites (which is more likely to happen the less those call sites are, among other factors) (which is what you've done already, so I'm guessing this didn't work in your case 12 years ago. :D)
I have .lib file with its header (.h) file. This file have a few functions that need to be used in C# application.
After googling I found that I need to create a dynamic DLL from this static library and call this dynamic DLL from C# code using interop.
I have created a win32 project and selected type DLL.
Included header file and added .lib to additional dependencies.
I am able to see the functions defined in the static library (when I press ctrl + space).
As a total newbie I do not know how I can export the function, which is, in .lib with following signature:
void testfun( char* inp_buff, unsigned short* inp_len, char* buffer_decomp,unsigned *output_len,unsigned short *errorCode)
I want same signature in my dynamic DLL with a different name.
What to write in header file and .cpp file?
If you can recompile your lib, just add __declspec(dllexport) to the signatures of all of the functions you want to be exported.
void __declspec(dllexport) testfun( char* inp_buff, unsigned short* inp_len, char* buffer_decomp,unsigned *output_len,unsigned short *errorCode)
If you can't do that, then you can export them by writing a .def file instead. Using def files you can even change the name of a function as it is exported.
http://msdn.microsoft.com/en-us/library/28d6s79h.aspx
---- contents of mylib.def ----
LIBRARY
EXPORTS
testfun
newname=testfun2
Then when you link the dll, include mylib.def
link /dll /machine:x86 /def:mylib.def mylib.lib
Edit2:
note that pinvoke assumes that the functions you import will have _stdcall calling convention unless you say otherwise. So you might need to do this as well, in your C# code.
[DllImport("mylib.dll", CallingConvention=CallingConvention.Cdecl)]
Or, you could change your C++ code to be __stdcall
void __declspec(dllexport) __stdcall testfun( char* inp_buff, ...
This is what you can do
Add the following code to you .H file. rename "MYPROJECT" to your project name
#ifdef MYPROJECT_EXPORTS
#define MYPROJECT_API __declspec(dllexport)
#else
#define MYPROJECT_API _declspec(dllimport)
#endif
Go to Properties->C++->Preprocessor and Add the defenition - MYPROJECT_EXPORTS
Add MYPROJECT_API to all the functions you want the dll to expose eg:
MYPROJECT_API void Test();
Go to Project properties General -> Configuration Type change it to Dynamic Dll
You are done
Create new Dll project using Visual Studio Application Wizard, and check "Exports Symbols" in one of the Wizard steps. It creates sample Dll which exports class, function and variable. You can learn from this sample, how to do this.
Generally, every exported function is declared as __declspec(dllexport). In a client project it is declared as __declspec(dllimport). Dll code uses the constant which is defiled as __declspec(dllexport) inside of Dll project, and __declspec(dllimport) in any other place.
there are two versions of LIB can be generated,
the fist is the dynamic lib, (source file + header+ dynamic lib) --> to access the DLL
or static lib=(dynamic lib+DLL) --> (Source file+header) --> to access the DLL.
if you have the Dynamic Lib > there is no way to create the DLL (you cannot get something from nothing), dynamic lib is just an interface,
but if you have the Static Lib then there is no need to DLL to access it is functions.
Take a look at my answer to this question for a possible solution. Almost positive this will work for you...
In short: Enable the "Use Library Dependency Inputs" option in your Linker settings. If set to "true", it will force linking ALL symbols & code declared in every LIB specified as input to the project.
The issue here is not how the code is decorated, it's the extra step of creating a static library that contains all of the entry points, and trying to build the dll out of that.
If you go with the __delcspec approach and build the static library first, then try to link to it when building a DLL, you'll have to solve the dead-code stripping problem.
When you link, the obj srcs are used to find all of the decorated exports and dependencies are resolved, everything else is stripped. If you have no DLL src, so no obj files (except maybe a dll main), all of the code in the lib you want to export will be stripped (regardless of the attributes).
So, you either have to:
Tell the linker not to strip unused code, which is probably going to give you a lot of stuff you don't want.
Use a def file to expose the exports manually
Link the dll against the obj files used to create the lib instead of linking to the lib directly.
Or maybe create dummy code that references the functions you want to export from something you are exporting.
i'm wondering why linkers can not do their job simply by consulting the information in the actual .dll files that got the actual implementation code ? i mean why linkers still need .lib files to do implicit linking ?
are not the export and relative address tables enough for such linking ?
is there anyway by which one can do implicit linking using only the .dll without the .lib stub/proxy files ?
i thought the windows executable loader would simply do LoadLibrary/LoadLibraryEx calls on behalf of the program (hence the name implicit linking) which is the main difference to explicit linking. if that is true then doing it explicitly without .lib should indicate that it is doable without it implicitly, right ? or i'm just saying non sense?
I can think of a a few reasons.
Using .lib files mean you can build for a different version of a DLL than you have on your system, provided you just have the correct SDK installed.
Compilers & linkers need to support cross-platform compilations - You might be building for a 64-bit target on a 32-bit platform and vice-versa and not have the correct architecture DLL present.
.lib files enable you to "hide" certain parts of your implementation - you could have private exports that do not show up in the .lib but are discoverable via GetProcAddress. You can also do ordinal exports in which case they don't have a friendly name exported, but would have a friendly name in the .lib.
Native DLL's do not have strong names, so it may be possible to pick up the wrong version of the DLL.
And most importantly, this technology was designed in the 1980's. If it were designed today, it'd probably be closer to what you describe - for instance, .NET you just need to reference the target assembly and you have everything you need to use it.
I don't know of any way to do implicit linking solely with the DLL - A quick search revealed several tools, but I haven't used any of them.
In this case, I would create a separate source file with the functions you need to use, and dynamically load the DLL and bind them as needed. For example:
// using global variables and no-error handling for brevity.
HINSTANCE theDll = NULL;
typedef void (__stdcall * FooPtr)();
FooPtr pfnFoo = NULL;
INIT_ONCE initOnce;
BOOL CALLBACK BindDLL(PINIT_ONCE initOnce, PVOID parameter, PVOID context)
{
theDll = LoadLibrary();
pfnfoo = GetProcAddress(dll, "Foo");
return TRUE;
}
// Export for foo
void Foo()
{
// Use one-time init for thread-safe lazy initialization
InitOnceExecuteOnce(initOnce, BinDll, NULL, NULL)
pfnFoo();
}