Header files contain only the declaration of the function and the actual implementation of the function is in the library. If they don't want to share source code they can share the obj file.
Why do we use a Library when the implementation of a function can also be done in another C++ file?
Usually, a library is a collection of several translation units. A library archive is simply a convenient way to bundle the separate object files into one blob.
Besides that, shared libraries add the ability of dynamic loading and sharing of commonly used libraries between multiple dependents which isn't possible with a plain object file.
Libraries used in general as a collection of functions implements by other developers and can used by another developers " as a general used" , also provide a benefit to minimize your code and also u can take a function from library and edit the implementation as u need.
As other people explained I want to add more into it, Library provides you Reusability across multiple systems regardless of in which language they are written in Different Language unless it follows the same ABI. For example, A library written in C can be easily used with Rust, by wrapping the same function in Rust syntax.
For example, a function in C has this signature.
int return_num(int a);
If we write it in Rust, which will interact the same way as C do.
extern "C" {
fn return_num(x: i32) -> i32;
}
Related
Is it possible to use a C++ library from Rust when the library (e.g. Boost) uses templates (generics)?
Yes, but it may not be practical.
The D programming language is one of the very few providing some degree of C++ interoperability; you can read more about it on dlang.
Note the limitation for the template section:
Note that all instantiations used in D code must be provided by linking to C++ object code or shared libraries containing the instantiations.
which essentially means that you must use C++ code to cause the instantiation of the templates with the right types, and then the D compiler will link against those instantiations.
You could do the same for Rust. Without compiler support, this means mangling the names manually. In the FFI section, you will find the link attribute:
#[link(name = "snappy")]
extern {
fn snappy_max_compressed_length(source_length: size_t) -> size_t;
}
which tells the compiler which linked library will provide the symbol, you will also support for various calling conventions and the no_mangle attribute.
You may need to apply #[allow(non_snake_case)] as appropriate.
Servo uses bindgen to generate Rust bindings for C and C++ code; I am unclear on the level of C++ support, and somewhat doubtful that it can handle templates.
I'm trying to use a shared library written in C++ from other programs. I have done the shared library and I have tested that it works.
The shared library mentioned above has dependencies to other libraries. I have avoided this problem compiling my shared library telling the linker where to find that dependencies, and deploying that shared library with all its dependencies into a folder.
The problem
Now my problem is the header files. I have a header file to deploy with my shared library, but this header file also includes 3rd-party headers. For example, I have my shared library A, with its header file AH. AH needs to include BH and CH header files to get their definitions, and this is what I want to avoid.
Then, I think the solution could be to use the extern keyword on the 3rd-party functions that I need. The problem with this is that I also need the definitions of some structs (that are declared in the 3rd-party header files mentioned above). So, how can I include this struct definitions using the extern keyword? Is there any better way to do what I want?
I have a header file to deploy with my shared library
Why? Headers are required only at compile time. You do not need to provide headers along with the library if all you want to do is run programs that use it.
But maybe you do want to provide for building additional programs that use your library.
but this header file also includes 3rd-party headers. For example, I have my shared library A, with its header file AH. AH needs to include BH and CH header files to get their definitions, and this is what I want to avoid.
You're not making much sense. If AH requires definitions (or maybe you really mean declarations) provided by BH and CH then you have only two options:
Ensure that BH and CH are available, or
Provide alternative, compatible versions of the definitions / declarations that AH requires.
You describe needing function declarations. Certainly if you have calls to B and C functions in AH, then you need full declarations of those functions. Function declarations are extern by default, so no worries there, but it is essential to have full prototypes. You could copy those from BH and CH if you wanted, though that's a bit questionable.
You also describe needing struct declarations. Type declarations have no linkage, so extern is irrelevant to them; extern would matter here only if you were talking about global variables. You do not need complete declarations of the structs if you use only opaque pointers to instances of those structs. That means never instantiating them directly; never dereferencing them, not even to invoke methods on them; and generally never doing anything that depends on their size or layout. If your usage -- including in your own header file AH -- meets those requirements, then instead of complete declarations of the structs in question you can provide your own, incomplete ones:
struct b_struct;
Of course, since you can't do anything directly with pointers to those, that only makes sense if the pointers to them are provided by functions from libraries B and C, and your own code does nothing with them apart from store them and pass them as function or method arguments. If you need them in any more substantial capacity, then you do need the full declarations. Like with the functions, you can copy those. Even more than with the functions, that's questionable.
More generally, you inquire
how can I include [...] definitions using the extern keyword?
It is essential to understand that extern is about linkage. It is primarily concerned with the run-time visibility of functions, methods, and variables. It relates to compile-time visibility only inasmuch as the compiler and linker implement linkage rules. Slapping the extern keyword on the declaration of a struct type does not magically make that type visible to code that does not contain an actual declaration of that type.
assume we were using gcc/g++ and a C API specified by a random committee. This specification defines the function
void foo(void);
Now, there are several implementations according to this specification. Let's pick two as a sample and call them nfoo and xfoo (provided by libnfoo and libxfoo as static and dynamic libraries respectively).
Now, we want to create a C++ framework for the foo-API. Thus, we specify an abstract class
class Foo
{
public:
virtual void foo(void) = 0;
};
and corresponding implementations
#include <nfoo.h>
#include "Foo.h"
class NFoo : public Foo
{
public:
virtual void foo(void)
{
::foo(); // calling foo from the nfoo C-API
}
};
as well as
#include <xfoo.h>
#include "Foo.h"
class XFoo : public Foo
{
public:
virtual void foo(void)
{
::foo(); // calling foo from the xfoo C-API
}
};
Now, we are facing a problem: How do we create (i.e. link) everything into one library?
I see that there will be a symbol clash with the foo function symbols of the C API implementations.
I already tried to split the C++ wrapper implementations into separate static libraries, but then I realized (again) that static libraries is just a collection of unlinked object files. So this will not work at all, unless there is a way to fully link the C libraries into the wrapper and remove/hide their symbols.
Suggestions are highly appreciated.
Update: Optimal solutions should support both implementations at the same time.
Note: The code is not meant to be functional. Perceive it as pseudo code.
Could you use dlopen/dlsym at runtime to resolve your foo call.
something like example code from link ( may not compile):
void *handle,*handle2;
void (*fnfoo)() = null;
void (*fxfoo)() = null;
/* open the needed object */
handle = dlopen("/usr/home/me/libnfoo.so", RTLD_LOCAL | RTLD_LAZY);
handle2 = dlopen("/usr/home/me/libxfoo.so", RTLD_LOCAL | RTLD_LAZY);
fnfoo = dlsym(handle, "foo");
fxfoo = dlsym(handle, "foo");
/* invoke function */
(*fnfoo)();
(*fxfoo)();
// don't forget dlclose()'s
otherwise, the symbols in the libraries would need to be modified.
this is not portable to windows.
First thing's first, if you are going to be wrapping up a C API in C++ code, you should hide that dependency behind a compilation firewall. This is to (1) avoid polluting the global namespace with the names from the C API, and (2) freeing the user-code from the dependency to the third-party headers. In this example, a rather trivial modification can be done to isolate the dependency to the C APIs. You should do this:
// In NFoo.h:
#include "Foo.h"
class NFoo : public Foo
{
public:
virtual void foo(void);
};
// In NFoo.cpp:
#include "NFoo.h"
#include <nfoo.h>
void NFoo::foo(void) {
::foo(); // calling foo from the nfoo C-API
}
The point of the above is that the C API header, <nfoo.h>, is only included in the cpp file, not in the header file. This means that user-code will not need to provide the C API headers in order to compile code that uses your library, nor will the global namespace names from the C API risk clashing with anything else being compiled. Also, if your C API (or any other external dependency for that matter) requires creating a number of things (e.g., handles, objects, etc.) when using the API, then you can also wrap them in a PImpl (pointer to a forward-declared implementation class that is only declared-defined in the cpp file) to achieve the same isolation of the external dependency (i.e., a "compilation firewall").
Now, that the basic stuff is out of the way, we can move to the issue at hand: simultaneously linking to two C APIs with name-clashing symbols. This is a problem and there is no easy way out. The compilation firewall technique above is really about isolating and minimizing dependencies during compilation, and by that, you could easily compile code that depends on two APIs with conflicting names (which isn't true in your version), however, you will still be hit hard with ODR (One Definition Rule) errors when reaching the linking phase.
This thread has a few useful tricks to resolving C API name conflicts. In summary, you have the following choices:
If you have access to static libraries (or object files) for at least one of the two C APIs, then you can use a utility like objcopy (in Unix/Linux) to add a prefix to all the symbols in that static library (object files), e.g., with the command objcopy --prefix-symbols=libn_ libn.o to prefix all the symbols in libn.o with libn_. Of course, this implies that you will need to add the same prefix to the declarations in the API's header file(s) (or make a reduced version with only what you need), but this is not a problem from a maintenance perspective as long as you have a proper compilation firewall in place for that external dependency.
If you don't have access to static libraries (or object files) or don't want to do this above (somewhat troublesome) approach, you will have to go with a dynamic library. However, this isn't as trivial as it sounds (and I'm not even gonna go into the topic of DLL Hell). You must use dynamic loading of the dynamic link library (or shared-object file), as opposed to the more usual static loading. That is, you must use the LoadLibrary / GetProcAddress / FreeLibrary (for Windows) and the dlopen / dlsym / dlclose (all Unix-like OSes). This means that you have to individually load and set the function-pointer address for each function that you wish to use. Again, if the dependencies are properly isolated in the code, this is going to be just a matter of writing all this repetitive code, but not much danger involved here.
If your uses of the C APIs is much simpler than the C APIs themselves (i.e., you use only a few functions out of hundreds of functions), it might be a lot easier for you to create two dynamic libraries, one for each C API, that exports only the limited subset of functions, giving them unique names, that wrap calls to the C API. Then, you main application or library can be link to those two dynamic libraries directly (statically loaded). Of course, if you need to do that for all the functions in that C API, then there is no point in going through all this trouble.
So, you can choose what seems more reasonable or feasible for you, there is no doubt that it will require quite a bit a manual work to fix this up.
if you only want to access one library implementation at a time, a natural way to go about it is as a dynamic library
in Windows that also works for accessing two or more library implementations at a time, because Windows dynamic libraries provide total encapsulation of whatever's inside
IIUC ifdef is what you need
put #define _NFOO
in the nfoo lib and #define XFOO in xfoo lib.
Also remember if nfoo lib and xfoo lib both have a function called Foo then there will be error during compilation. To avoid this GCC/G++ uses function overloading through name mangling.
you can then check if xfoo is linked using ifdefs
#ifdef XFOO
//call xfoo's foo()
#endif
A linker cannot distinguish between two different definitions of the same symbol name, so if you're trying to use two functions with the same name you'll have to separate them somehow.
The way to separate them is to put them in dynamic libraries. You can choose which things to export from a dynamic library, so you can export the wrappers while leaving the underlying API functions hidden. You can also load the dynamic library at runtime and bind to symbols one at a time, so even if the same name is define in more than one they won't interfere with each other.
I know there are differences in the source code between C and C++ programs - this is not what I'm asking about.
I also know this will vary from CPU to CPU and OS to OS, depending on compiler.
I'm teaching myself C++ and I've seen numerous references to libraries that can be used by both languages. This has started me thinking - are there significant differences between the binary executables of the two languages?
For libraries to be easily used by both, I would think they'd have to be similar on an executable level.
Are there many situations where a person could examine a executable file and tell whether it was created by C or C++ source code? Or would the binaries be pretty similar?
In most cases, yes, it's pretty easy. Here are just a few clues that I've seen often enough to remember them easily:
C++ program will typically end up with at least a few visible symbols that have been mangled.
C++ program will typically have at least a few calls to virtual functions, which are typically quite distinctive from code you'll typically see in C.
Many C++ compilers implement a calling convention for C++ that gives special consideration to passing the this pointer into C++ member functions. Again, since the this pointer simply doesn't exist in C, you'll rarely see a direct analog (though in some cases, they will use the same convention to pass some other pointer, so you need to be careful about this one).
A executable is a executable is a executable, no matter what language it's written in. If it's built for the target architecture, it'll run on the architecture.
The (arguably) most important difference between C and C++-compiled code, and the one relevant to libraries that can be linked both against C and C++ executables, is that of name mangling. Basically: when a library is compiled, it exports a set of symbols (function names, exported variables, etc.) that executables linked against the library can use. How these symbols are named is a fairly compiler/linker-specific, and if the subsequent executable is linked using a linker using an incompatible convention, then symbols won't resolve correctly. In addition, C and C++ have slightly different conventions. The Wikipedia article linked above has more of the details; suffice to say, when declaring exported symbols in a header file, you'll usually see a construction like:
#ifdef __cplusplus
extern "C" {
#endif
/* exported declarations here */
#ifdef __cplusplus
}
#endif
__cplusplus is a preprocessor macro only defined when compiling C++ code. The idea here is that, when using the header in C++, the compiler is instructed to use the C way of naming exported symbols (inside the "extern "C" { /* foo */ }" block, so the library can be linked both in C and C++ correctly.
I think I could tell if something is C++ or C from reading the disassembled binary code [for processor architectures that I'm familiar with, x86, x86_64 and ARM]. But in reality, there isn't much difference, you'd have to look pretty hard to know for sure.
Signs to look for are "indirect calls" (function pointer calls via a table) and this-pointers. Although C can have pointer to struct arguments and will often use function pointers, it's not usually set up in the way that C++ does it. Also, you'll notice, sometimes, that the compiler takes a pointer to a struct and adds a small offset - that's removing the outer layer of an inherited class. This CAN happen in C as well, but it won't be as common/distinctive.
Looking just at the binary [unless you can "do disassembly in your head" would be a lot harder - especially if it's been stripped of symbols - that's like the guy who could tell you what classical music something was on an old Vinyl record from looking at the tracks [with the label hidden] - not something most people can do, even if they are "good".
In practice, a C program (or a C++ program) is rarely only pure standard C (or C++) (for instance the C99 standard has no mean to scan a directory). So programs use additional libraries.
On Linux, most binaries are dynamically linked. Use the ldd command to find out.
If the binary is linked to the stdc++ library, the source code is likely C++.
If only the libc.so library is linked, the source code is probably only C (but you could link statically the libstdc++.a library).
You can also use tools working on binary files (e.g. objdump, readelf, strings, nm on Linux ....) to find more about them.
The code generated by C and C++ compilers is generally the same code. There are two important differences:
Name mangling: Each function and global variable becomes a symbol at compile time. In C these symbol's names are the same as their names in your source code. In C++ they are being mangled a bit to allow for polymorphic code
Calling conventions: If you call a method in C++ the this-pointer is passed as a hidden first parameter. Other conventions might also be different such as call by reference which does not exist in C
You can use an block such as this to let the C++-compiler generate code compatible to C:
extern "C" {
/* code */
}
I have a small doubt.
I am adding some extra functions in a C++ code and these functions are getting called by functions of a class.
Is it necessary to make these extra functions a part of class or can a C++ class function call a C function?
If yes, how should the makefile be modified ?
Thanks!
As long as you have included some declaration and the C function is linked in it some point in the compilation, you can call C functions in any C++ function. For instance:
mycfunc.h:
void test(int x);
myfunc.c:
void test(int x) {
printf("%d\n", x);
}
Now, simply include the header file where you want to use the function. In your Makefile, simply make sure you include "myfunc.c" (or .o if you're compiling objects) in the final compilation.
C++ is not a pure object oriented language.
So you can use imperative form as it is in C ( even if it's modular or not ).
Some C functions not encapsulated in Objects are accessible using c* includes (ctime for instance).
You do not need to put them in a class. Functions exist in C++ just as in C so you can just use them. Just try it and ask again if you have trouble.
As you state that you add functions to a C++ project, just treat (and think of) all your code as C++. Put your new stuff in files using the same filename extensions as those of the rest of the project.
Edit in response to comment from OP:
Yes, no need to think about the distinction between C and C++ in this case. Just write .cpp files. And in the makefile, just add those files just as the other files are listed there.
The distinction between C and C++ is important if you have existing C++ code and need to use if from C, or for example if you have existing C libraries and need to call that from C++. In your case there's very likely no reason not to stick to C++. Unlike Java, it's completely natural to have free standing functions. There even many in the C++ standard library.
Now, if in your case it is good design to have free standing functions instead of adding to classes (modifying or using inheritance) is hard to tell given the information you have posted. But, if what you need to do can be done in a natural way without accessing the private parts of existing classes the answer may very well be yes.