Recently I started to work with c++. I heard about exported functions but not sure what it means.
so my questions are about:
What is exported function?
Is there any difference between normal function and exported function? if yes, what is it?
How is it related with dll?
what is exported function ?
When you program with modules (pieces of code) you need to call in some module a function which was defined in some other module. Exporting is relative to that process. In C/C++ if you want to declare a function to use it without defining it in a source file, you should use the keyword "extern". In the file where that function is defined you have nothing special to make, by defaults things at global scope are automatically exported.
Is there any difference between normal function and exported function? if yes , what it is ?
Nothing special, except that the later are visible at link time.
how it is related with dll ?
See, http://msdn.microsoft.com/en-us/library/a90k134d.aspx for DLL and function export for DLL. In such a case you must declare which function should be exported.
Related
I have inherited a large C++ project in which a multithreaded executable loads a few dozen DLLs. On Windows, the DLLs are loaded using LoadLibrary(), and the entry points to the DLLs are accessed using GetProcAddress().
One of the entry points in each DLL is a function called MyEntryPoint, declared like this on Windows:
extern "C" __declspec(dllexport) void MyEntryPoint()
MyEntryPoint() needs to call helper functions inside the DLL where it is defined. The helper functions do not need to be exported outside of the DLL in which they are declared because they are used only locally. However, several DLLs have functions with the same name. Example: in several DLLs, there is a function declared as:
void MyHelperFunction()
which is called by MyEntryPoint(). In some DLLs, MyHelperFunction() is declared static, but not in others. (Over the years, there have been many hands in the code, with varying levels of understanding and expertise.) Does declaring MyHelperFunction() as static avoid cluttering the global namespace, or is there another reason for doing it?
If library interface is defined via explicit __declspec((dllexport) annotations static won't cause any changes. If library interface is defined via .def file (which is unlikely), declaring function as static would preclude it's usage in .def file.
In addition to above, static would inform compiler that function is only accessible from current translation unit which allows more optimizations (e.g. inlining and cloning are done more aggressively) so it's always beneficial to use it.
I am working on a factory that will have types added to them, however, if the class is not explicitly instiated in the .exe that is exectured (compile-time), then the type is not added to the factory. This is due to the fact that the static call is some how not being made. Does anyone have any suggestions on how to fix this? Below is five very small files that I am putting into a lib, then an .exe will call this lib. If there is any suggestions on how I can get this to work, or maybe a better design pattern, please let me know. Here is basically what I am looking for
1) A factory that can take in types
2) Auto registration to go in the classes .cpp file, any and all registration code should go in the class .cpp (for the example below, RandomClass.cpp) and no other files.
BaseClass.h : http://codepad.org/zGRZvIZf
RandomClass.h : http://codepad.org/rqIZ1atp
RandomClass.cpp : http://codepad.org/WqnQDWQd
TemplateFactory.h : http://codepad.org/94YfusgC
TemplateFactory.cpp : http://codepad.org/Hc2tSfzZ
When you are linking with a static library, you are in fact extracting from it the object files which provide symbols which are currently used but not defined. In the pattern that you are using, there is probably no undefined symbols provided by the object file which contains the static variable which triggers registration.
Solutions:
use explicit registration
have somehow an undefined symbol provided by the compilation unit
use the linker arguments to add your static variables as a undefined symbols
something useful, but this is often not natural
a dummy one, well it is not natural if it is provided by the main program, as a linker argument it main be easier than using the mangled name of the static variable
use a linker argument stating that all the objects of a library have to be included
dynamic libraries are fully imported, thus don't have that problem
As a general rule of thumb, an application do not include static or global variables from a library unless they are implicitly or explicitly used by the application.
There are hundred different ways this can be refactored. One method could be to place the static variable inside function, and make sure the function is called.
To expand on one of #AProgrammer's excellent suggestions, here is a portable way to guarantee the calling program will reference at least one symbol from the library.
In the library code declare a global function that returns an int.
int make_sure_compilation_unit_referenced() { return 0; }
Then in the header for the library declare a static variable that is initialized by calling the global function:
extern int make_sure_compilation_unit_referenced();
static int never_actually_used = make_sure_compilation_unit_referenced();
Every compilation unit that includes the header will have a static variable that needs to be initialized by calling a (useless) function in the library.
This is made a little cleaner if your library has its own namespace encapsulating both of the definitions, then there's less chance of name collisions between the bogus function in your library with other libraries, or of the static variable with other variables in the compilation unit(s) that include the header.
Is it possible to call a function in a C++ DLL from C code?
The function is not declared extern "C".
An ugly platform dependent hack that only works with Visual Studio is fine.
Calling conventions should not be a major issue, but how do I deal with name mangling.?
For instance with Visual Studio, a C++ function with signature void f() has the mangled name ?f##YAXXZ and that is not a legal C identifier.
(You don't need to tell me that I should declare the C++ function as extern "C".
I already know that. But I'm in a situation where I cannot change the C++ code.)
Wrap the offenging function in another C++ function, and declare it with extern "C". No need to create a special DLL for it, just include one C++ file in your project.
To make your compiler to statically link a function with a different exported name may be tricky. But you can always load the DLL with LoadLibrary and then use GetProcAddress.
You could investigate
LoadLibrary("path to dll");
to load the DLL and
GetProcAddress("?f##YAXXZ");
to grab a function pointer to the externally declared function.
I do not see any clean solution besides creating an additional dll written in C++ and exposing all interfaces via extern "C".
You could compile your C code using the same C++ compiler they used, then your C functions will be mangled using the same mechanism and everything will link seamlessly, and no-one will notice any difference.
If you must use a different compiler, then you'll have to manually load the dll using LoadLibrary and each function using GetProcAddress.
I was wondering if there is any way to make something like plugin in Java, so main program loads sub-programs and execute their functions. I thought about set of small programs that return some value, but I want to make the plugins able to modify some of the main program objects (maybe pass the pointer somehow?).
Is there any way to do this?
Thanx for any replies.
It is possible to dynamically load code at run-time in the form of dynamically linked libraries (DLL:s in Windows).
The approach (when dealing with Windows at least) I use is about this:
Create a dll with some exported functions (declared with __declspec(dllexport))
Load the created file at run-time with the LoadLibrary function in the Windows-API
Get the function-pointer to a member function by its name with the function GetProcAddress-function using the name of the function.
The last part may be a little confusing sometimes as C++ uses name-mangling to keep track of return types and such things. This means that the name stored in the DLL is not the name of the function, but a name also containing descriptions of the function's parameter types and such things.
To prevent the name-mangling, you can declare the exported functions with extern "C", such as
extern "C" __declspec(dllexport) int myFunction(...);
However, this will not allow for classes in the function declaration.
An important thing to consider when passing pointers to data structures between the dynamically linked library and the "main program" is to make sure that the declaration of the type is the same in the two files (easily accomplished by sharing the header declaring the type), otherwise there will be severe errors when executing your program.
Again, this is probably Windows-specific, but it might give you a hint of the correct procedure on your system.
I am working on a factory that will have types added to them, however, if the class is not explicitly instiated in the .exe that is exectured (compile-time), then the type is not added to the factory. This is due to the fact that the static call is some how not being made. Does anyone have any suggestions on how to fix this? Below is five very small files that I am putting into a lib, then an .exe will call this lib. If there is any suggestions on how I can get this to work, or maybe a better design pattern, please let me know. Here is basically what I am looking for
1) A factory that can take in types
2) Auto registration to go in the classes .cpp file, any and all registration code should go in the class .cpp (for the example below, RandomClass.cpp) and no other files.
BaseClass.h : http://codepad.org/zGRZvIZf
RandomClass.h : http://codepad.org/rqIZ1atp
RandomClass.cpp : http://codepad.org/WqnQDWQd
TemplateFactory.h : http://codepad.org/94YfusgC
TemplateFactory.cpp : http://codepad.org/Hc2tSfzZ
When you are linking with a static library, you are in fact extracting from it the object files which provide symbols which are currently used but not defined. In the pattern that you are using, there is probably no undefined symbols provided by the object file which contains the static variable which triggers registration.
Solutions:
use explicit registration
have somehow an undefined symbol provided by the compilation unit
use the linker arguments to add your static variables as a undefined symbols
something useful, but this is often not natural
a dummy one, well it is not natural if it is provided by the main program, as a linker argument it main be easier than using the mangled name of the static variable
use a linker argument stating that all the objects of a library have to be included
dynamic libraries are fully imported, thus don't have that problem
As a general rule of thumb, an application do not include static or global variables from a library unless they are implicitly or explicitly used by the application.
There are hundred different ways this can be refactored. One method could be to place the static variable inside function, and make sure the function is called.
To expand on one of #AProgrammer's excellent suggestions, here is a portable way to guarantee the calling program will reference at least one symbol from the library.
In the library code declare a global function that returns an int.
int make_sure_compilation_unit_referenced() { return 0; }
Then in the header for the library declare a static variable that is initialized by calling the global function:
extern int make_sure_compilation_unit_referenced();
static int never_actually_used = make_sure_compilation_unit_referenced();
Every compilation unit that includes the header will have a static variable that needs to be initialized by calling a (useless) function in the library.
This is made a little cleaner if your library has its own namespace encapsulating both of the definitions, then there's less chance of name collisions between the bogus function in your library with other libraries, or of the static variable with other variables in the compilation unit(s) that include the header.