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.
Related
So I'm working on a static C library (like a library.a file) for a school project. There are multiple functions, some of which are placed in different files, so I can't use the static keyword. Is there a way that those functions could be limited to the library itself, an equivalent to static for libraries?
So I'm working on a static C library (like a library.a file) for a school project. There are multiple functions, some of which are placed in different files, so I can't use the static keyword. Is there a way that those functions could be limited to the library itself, an equivalent to static for libraries?
The C language does not have any formal sense of a unit of program organization larger than a single translation unit but smaller than a whole program. Libraries are a foreign concept to the language specification, provided by substantially all toolchains, but not part of the language itself. Thus, no, the C language does not define a mechanism other than static to declare that a function identifier can be referenced only by a proper subset of all translation units contributing to a program.
Such limitations are supported by some shared library formats, such as ELF, and it is common for C implementations targeting such shared libraries to provide extensions that enable those facilities to be engaged, but the same generally is not true for static libraries.
Note also that in all these cases, we're talking about the linkage of function identifiers, not about genuinely controlling access to the functions. In principle, any function in the program can be called from anywhere in the program via a function pointer pointing to it.
Frame challenge: why do you care?
The usual accommodation for having functions with external linkage that you don't want library clients to call directly would be to omit those functions from the library's public header files. What does it matter if some intrepid person can analyze the library to discover and possibly call those functions? Your public headers and documentation tell people how the library should be used. If people use it in other ways then that's on them.
It may not be possible to completely "hide" the existence of a set of restricted functions from other source files if they are defined with external linkage, since their identifiers will be visible when linking (as noted in the other answer).
However, if you are only looking to prevent someone from inadvertently calling restricted functions, one of these approaches may be useful:
In some of my projects, I have used #define and #ifdef statements to block restricted functions from being used throughout the program. For example, in my Hardware Abstraction Layer (HAL) library C source files, I typically place #define HAL__ prior to any #include statements. Then I place an #ifdef HAL__ ... #endif block around any restricted function definitions in my header files. Someone with intention could easily easily bypass this by adding #define HAL__ to their source code or by modifying the header file, but it provides some protection against unintentional use of restricted functions and other definitions.
Place the restricted function definitions in a separate header file used to build the library itself (for example library.a) and provide only header files containing non-restricted function declarations with the library. The identifiers for any functions defined will still be visible to the linker, but without the prototypes, it will be difficult for anyone to call them.
Again, if having the identifiers for any restricted functions visible throughout the program would be a problem (for example, duplicating other identifiers), then these options will not work. Also, if the goal is to prevent developers from intentionally calling restricted functions, then these options will not work, although option 2 would make this more difficult. If the intention is only to prevent unintentional calls to the restricted functions and there is no concern with having duplicate identifiers in the program, then these options may help.
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.
When we include the header files in C , we actually add the declaration of the functions such as the printf , scanf etc. But how does the code for the function ( the function declaration ) get added to the program ?
That's done by the process of linking. Individually compiled translation units have a way of referring to dependent names symbolically, so your code would only say "call a function with name 'printf'", and it is the job of the linking procedure to look up those symbols in one of the provided object or library files.
The standard library is usually linked against your code implicitly, so you may not be aware of the fact that you are linking your code with pre-existing library code. You would definitely be aware of this if you used your own libraries.
Note that there is no standard for linking, so you cannot generally compile one file with one compiler and another file with a different compiler and then link them together. The problem is not just to agree on how names are represented, but also on how to generate code for function calls. There are however several "informal" calling conventions and name mangling rules on popular platforms that offer a degree of interoperability.
Declaring a global variable with the same name as a standard function produces an error in clang (but not gcc). It is not due to a previous declaration in a header file. I can get the error by compiling the following one-line file:
extern void *memcpy[];
Clang says
foo.c:1:14: error: redefinition of 'memcpy' as different kind of symbol
foo.c:1:14: note: previous definition is here
Apparently this only happens for a few standard functions. printf produces an error, fprintf produces a warning, fseek just works.
Why is this an error? Is there a way to work around it?
Motivation. I am using the C compiler as a compiler backend. C code is programmatically generated. The generated code relies on byte-level address arithmetic and pointer type casting. All external symbols are declared as extern void *variablename[];.
According to the C standard (ISO 9899:1999 section 7.1.3), "all external identifiers defined by the library are reserved in a hosted environment. This means, in effect, that no user-supplied external names may match library names."
Your problem can be easily solved by adding a unique prefix to all your identifiers, e.g. "mylang_".
As an alternative, you can avoid the problem by using the LLVM or GCC -ffreestanding flag, which will compile your code for a non-hosted environment. (The C standard specifies that the restriction only applies to a hosted environment.) In this case you can use all the names you want (apart from main, which is still your program's entry point), but you must make your own arrangements for your library. This is how operating system kernels can legally define their own versions of the C library functions.
The reason is explained here and a relevant extract is given below. http://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html
I get an error in gcc as well.
The names of all library types, macros, variables and functions that come from the ISO C standard are reserved unconditionally; your program may not redefine these names. All other library names are reserved if your program explicitly includes the header file that defines or declares them. There are several reasons for these restrictions:
Other people reading your code could get very confused if you were using a function named exit to do something completely different from what the standard exit function does, for example. Preventing this situation helps to make your programs easier to understand and contributes to modularity and maintainability.
It avoids the possibility of a user accidentally redefining a library function that is called by other library functions. If redefinition were allowed, those other functions would not work properly.
It allows the compiler to do whatever special optimizations it pleases on calls to these functions, without the possibility that they may have been redefined by the user. Some library facilities, such as those for dealing with variadic arguments (see Variadic Functions) and non-local exits (see Non-Local Exits), actually require a considerable amount of cooperation on the part of the C compiler, and with respect to the implementation, it might be easier for the compiler to treat these as built-in parts of the language.
The page also describes other restricted names.
The premise: I'm writing a plug-in DLL which conforms to an industry standard interface / function signature. This will be used in at least two different software packages used internally at my company, both of which have some example skeleton code or empty shells of this particular interface. One vendor authors their example in C/C++, the other in Fortran.
Ideally I'd like to just have to write and maintain this library code in one language and not duplicate it (especially as I'm only just now getting some comfort level in various flavors of C, but haven't touched Fortran).
I've emailed off to both our vendors to see if there's anything specific their solvers need when they import this DLL, but this has made me curious at a more fundamental level. If I compile a DLL with an exposed method void foo(int bar) in both C and Fortran... by the time it's down to x86 machine instructions - does it make any difference in how that method is called by program "X"? I've gathered so far that if I were to do C++ I'd need the extern "C" bit to avoid "mangling" - there anything else I should be aware of?
It matters. The exported function must use a specific calling convention, there are several incompatible ones in common use in 32-bit code. The calling convention dictates where the function arguments are stored, in what order they are passed and how they are removed again. As well as how the function return value is passed back.
And the name of the function matters, exported function names are often decorated with extra characters. Which is what extern "C" is all about, it suppresses the name mangling that a C++ compiler uses to prevent overloaded functions from having the same exported name. So the name is one that the linker for a C compiler can recognize.
The way a C compiler makes function calls is pretty much the standard if you interop with code written in other languages. Any modern Fortran compiler will support declarations to make them compatible with a C program. And surely this is something that's already used by whatever software vendor you are working with that provides an add-on that was written in Fortran. And the other way around, as long as you provide functions that can be used by a C compiler then the Fortran programmer has a good chance at being able to call it.
Yes it has been discussed here many many times. Study answers and questions in this tag https://stackoverflow.com/questions/tagged/fortran-iso-c-binding .
The equivalent of extern "C" in fortran is bind(C). The equivalency of the datatypes is done using the intrinsic module iso_c_binding.
Also be sure to use the same calling conventions. If you do not specify anything manually, the default is usually the same for both. On Linux this is non-issue.
extern "C" is used in C++ code. So if you DLL is written in C++, you mustn't pass any C++ objects (classes).
If you stick with C types, you need to make sure the function passes parameters in a single way e.g. use C's default of _cdecl. Not sure what Fortran uses.