I'm in the process of switching from a def file to using _declspec for a library I maintain. I have read several of the questions here on SO and the MSDN documentation. I understand how the feature works. I have created macros and use _declspec or gcc __attribute__ depending on the build environment. The macros also properly select between _declspec(dllexport) and _declspec(dllimport).
Is there any harm in using _declspec on the function definitions? Should _declspec only be used on the function prototypes?
I would prefer to have the marco on both the function prototype and definition. I did test using _declspec on both the function prototype and definition. Using VS the library compiled without warnings and I was able to use the library without issue.
NO harm on function defination - sing __declspec(dllimport) is optional on function declarations, but the compiler produces more efficient code if you use this keyword. However, you must use __declspec(dllimport) for the importing executable to access the DLL's public data symbols and objects.
It is mostly used for importing symbols from / exporting symbols to a shared library (DLL). Both Visual C++ and GCC compilers support __declspec(dllimport) and __declspec(dllexport).
You can also use it for variables.
Related
For a predefined function where are the declaration and definition stored?
And is the declaration stored in libraries? If so, then why it is named library function?
This is an imprecise question. The best answers we can give are:
The declaration of standard library functions can best be thought of as being stored in their header files.
Depending on how you want to think about it, the definition of standard library files is either in the source files for those libraries (which may be invisible to you, a trade secret of your compiler vendor), or in the library files themselves (.a, .so, .lib, or .dll).
These days, knowledge of standard library functions is typically built in to the compiler, also. For example, if I write the old classic int main() { printf("Hello, world!\n"); }, but without any #include directives, my compiler says, "warning: implicitly declaring library function 'printf'" and "include the header <stdio.h>".
There are two sides of this story:
The code that calls a library/external function: The compiler generates a reference in your compiled module that encodes which function prototype you expect to exist elsewhere.
The pre-compiled library files against which your code must be linked: A library file contains both the coded prototypes of its functions as well as the actual compiled binary (i.e. the definition/implementation) for these function.
When your code uses an external function, the compiler generates a reference to this function that it assumes will be resolved later during the linking phase.
During the linking process lists of function references are build up. The linker expects to find the 'definition'/implementation of each of the used references.
The header file contains the declaration of built-in functions and the library contains the definition of the functions.
The name library is because, in my opinion, as the actual library which contains books, these libraries contain the classes, functions, variables etc.
I am doing some implementation about calling function of shared library via Java to JNI.
And JNI is implemented by C code.
Here is my question.
There is a function named ABC() in shared library.
This function is not be declared in header files.
BUT with NDK build, it can be successful and this function also can work fine.
It's very confusing.
Why? why can it be built by NDK and why can it be called without any exception?
Thank you for answering:)
There are two possibilities here.
The file using the function may contain its own declaration of the function. (Declarations are not required to be only in header files.)
If you use a function without declaring it, the compiler may provide a default declaration. This is not part of modern C, but compilers may use old standards or be unduly lax in this regard. The default declaration is a function of the type int SomeName(). Such implicit declarations automatically have external linkage, which means the name will be matched to the definition of the function when the library is linked in.
If the latter is the case, you would be well advised to enable additional switches to tell the compiler to issue more warning messages and to use a modern language standard (such as C 2011), at least when developing new code.
Using a routine that is in a shared library but is not declared in its header is inadvisable. Such routines are often intended only for internal use of the library, and they may change or vanish in future versions of the library. So code using them would break; it would not be compatible with the new versions of the library.
I have a static library project (written in C language) and another sample project (written in C language) under Visual Studio 2015. I can use the functions located at the library in the sample project without any problem. My problem is that I have a macro in one of the header files in the static library project and I can't see (or use) this macro in the sample project. I receive this error: "unresolved external symbol ADD1 referenced in function main". How can I use this macro in the sample project?
Note: I use the library file in the sample project thanks to this pragma this pragma: #pragma comment(lib, "mylib.lib")
I do not want to include any of the header files of the static library project. They are not supposed to be seen by other projects.
I think there is some confusion.
To make use of any library, you must know about its functions, datatypes (e.g: enum, struct, typedef), macros, etc... This all comes together to form the library's 'API'.
Most libraries (not all) will have some internal headers. You are correct, these are not supposed to be seen by other projects, and will be used strictly internally.
All libraries will have some 'public' headers that define their API. A code base Without a public API is either useless, or actually an application that stands on its own.
Include your header with the #include directive, not with some pragma.
A header should be written so that it is the public interface to your library, even if the library code itself may not be open. Either the macro is public and can then be declared in the header, or it is not public in which case you should encapsulate it inside the library.
If the library code is pre-compiled and delivered as a binary, either declare it in a C file or in a H file that the caller does not have access to.
If I declare a function like this:
#ifdef TEST_EXPORTS
#define TEST_API __declspec(dllexport)
#else
#define TEST_API __declspec(dllimport)
#endif
TESTAPI int __stdcall myadd(int a, int b);
The symbol in the DLL is _myadd#8, which makes perfect sense to me (after few hours of reading other questions here, that is).
But the windows libraries seem to do something different. They also use __stdcall (disguised as WINAPI), but the symbols in the DLLs have no name decoration. If the method above where in the windows libs, the symbol would be myadd.
My guess is that they use a def file to alias the symbols. But why does my linker know this when I link to one of these DLLs?
The windows header files declare these functions with WINAPI, so if I call them, the linker should look for the decorated name, as it is a __stdcall function. Yet somehow the linker knows to drop the name decoration.
I've tried to replicate this by writing a small DLL and removing the name decoration with a def file. As expected I get linker errors as the linker is still looking for the decorated name. I've done this in pure C, to make sure that c++ name mangling does not effect it.
edit: to clarify, MSVC 14.0 / VS2015, 32-bit
There is some barely documented magic at work here. Lets look some WIN32 API function, like RegQueryValueExW. It is defined in the winreg.h file like this:
WINADVAPI LSTATUS APIENTRY RegQueryValueExW(...);
Where WIADVAPI is a __declspec(dllimport) and APIENTRY is a moniker for the __stdcall naming convention. Also note, that all functions in the header are declared as extern "C". So by all means, this function should use name decoration, and its DLL export should be _RegQueryValueExW#24. Yet when we are looking advapi32.dll exports using dumpbin /exports command, we see an undecorated name:
Now lets closely examine advapi32.lib file using dumpbin /headers advapi32.lib command:
Note the undecorate specifier, that allows to link decorated name to the undecorated export. You could achieve the same result for your dll using a def file with EXPORTS section containing undecorated names. See this article and this answer for the additional information.
Also, everything written above is valid only for the x86 applications. C functions in the x64 bit environment are linked without name decoration:
The form of decoration for a C function depends on the calling
convention used in its declaration, as shown in the following table.
This is also the decoration format that is used when C++ code is
declared to have extern "C" linkage. The default calling convention is
__cdecl. Note that in a 64-bit environment, functions are not decorated.
I am trying to provide access to a function linked in to an executable from a static library. The original static library defines the symbol with no access specifiers, and I was able to access the function using the method defined here, which works fine using MSVC as linked in symbols are hidden by default.
However, when using GCC, I need to export the function while using -Wl,--exclude-libs,ALL which keeps all other unnecessary symbols from being visibly exported from linked-in static libraries. The symbol in question is not referenced from the main application itself, however third party modules may attempt to dynamically use the symbol externally (ffi etc), hence the use of FORCE_UNDEFINED_SYMBOL.
The only symbols I need exported are those marked visibility default from the main application, and certain imported functions from static libraries (which I may not be able to modify). I know wrapper functions could be used, however I'm wondering if there is any other way.
So, is it possible to export a symbol (visibly) from a linked-in static library, while using -WL,--exclude-libs,ALL, without the use of any additional (version-lists etc) files, or commands/flags? (And without modifying the static library)
Using the following macros (partially) work, however the original function symbol is still .hidden (with __MyFunction_fp exported as visible).
#define APIEXPORT __attribute__ ((visibility ("default")))
#define FORCE_UNDEFINED_SYMBOL(x) extern APIEXPORT void x(void); APIEXPORT void* __ ## x ## _fp =(void*)&x;
FORCE_UNDEFINED_SYMBOL(MyFunction)
In this instance, the actual definition/declaration of MyFunction would exist in a static library, and cannot be changed.
EDIT: I discovered that the above macro FORCE_UNDEFINED_SYMBOL does not produce the desired symbol visibility under MSVC. It seems that the only working solution is using pragma comments, ie, __pragma(comment (linker, "/export:" #x)). Maybe a similar solution exists for gcc/ld.
What you're suggesting sounds hard to maintain even if you succeed. You want shared object (DLL) behavior with static libraries.
When I had a similar problem (e.g. 3rd party static lib) I wrapped the lib in a shared object and used that with my application.