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)
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 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.
In current g++, I typically include all my templated functions that take the template parameter as an argument because they have to be compiled for each instance.
template<typename T>
class A {
public:
void f() { ... }
};
So in a different source, I would write:
#include <A.hh>
A<int> a1;
a1.f();
A<double> a2;
a2.f();
Sometimes, when I've been desperate to not inline big methods, I've manually specified which classes will be used in the source file, but it's really obnoxious:
template<typename T>
A::A() { ... }
template<typename T>
void A::f() { ... }
A<int>; // manually trigger code generation for int and double
A<double>;
Obviously different IDEs and compilers have mechanisms to support this. Is there anything standard that has been mandated, and/or does g++ support anything like this?
There's nothing in the proposed C++0x standard. In fact, export template has been removed (few compilers implemented it anyway).
As far as inlining is concerned, it's a total non-issue. The compiler is smart enough not to inline functions which are too big, even if they're marked inline and put into a header file.
If you're looking at increased compile times from header files grown bloated from templates, use precompiled headers. These aren't standard, but almost all current compilers provide such a mechanism.
C++0x does have extern template, which allows you to prevent the instantiation of certain templates in a compilation unit. So if you have a template class SomeClass, you can put this in the header:
extern template SomeClass<int>;
extern template SomeClass<double>;
This will prevent users from instantiating the template. In the .cpp file for the template, you can force instantiation with this syntax:
template SomeClass<int>;
template SomeClass<double>;
I've manually specified which classes will be used in the source file, but it's really obnoxious:
A<int>; // manually trigger code generation for int and double
A<double>;
This is not legal (I assume you meant to declare dummy variables here, and missed their name). We will see below why
Is there anything standard that has been mandated, and/or does g++ support anything like this?
C++03 had something called export, but which turned out to be a misfeature. The EDG implemented that feature, and their experience with it indicated that it's not worth the trouble implementing it. And it doesn't provide a useful feature separate compilation usually gives you: Hiding of the code of templates which you once compiled. export still requires the code of templates, be it in raw form or encoded into a mid-level compiler-specific language. See Why we can't afford export. A short example is given by EDG worker David Vandevoorde here.
For C++0x and for C++0x sans export, we have
A function template, member function of a class template, or static data member of a class template shall be deļ¬ned in every translation unit in which it is implicitly instantiated (14.7.1) unless the corresponding specialization is explicitly instantiated (14.7.2) in some translation unit; no diagnostic is required
As this indicates, the only way you can achieve separate compilation is to explicitly instantiate the template you want to have separately compiled. By defining dummy variables, you merely implicitly instantiate the class template. And you do not instantiate the member functions of the class templates that way - you would need to do dummy calls or take their address. And to all this, you are not guaranteed that an implicitly instantiated function won't be discarded if it's not used in the translation unit it was instantiated by, after optimization, based on the above quote.
So you explicitly instantiate the class template, which will explicitly also instantiate its member functions the following way:
template class A<int>;
template class A<double>;
This feature, called export is present even in the current standard of C++. Unfortunately, most compilers, including gcc, do not support it. See here http://gcc.gnu.org/bugs/
I heard people talking about changing the interface of a dll.
What is a change in the interface of the dll, and how would you do that?
Changing a dll's interface would mean to change how the dll and the calling code interacts. This could mean changing the signatures of the dll's exporting functions, or changing to a different set of functions entirely, or it could mean passing different data from the calling code. A dll's interface is generally all it's exported and imported items (both functions and data), or in other words, the parts of the dll that you have access to when you use it.
Often you will want to change the behaviour of your dll without changing its interface. This is because changing the interface often will break code that uses it.
Imagine my dll exporting function foo:
void foo(int i)
{
// Does thing with integer
}
Changing the interface could mean changing foo's signature into
void foo(int, float);
Now, all the code that used foo previously has to be rewritten to use the new signature, which could be a bad thing.
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.