creating shared library using other library in linux - c

I have a shared library say "libeval.so". I am using this in my project to create on more shared library called say "lidpi.so". The library called "libdpi.so" is used by a tool. Now, this tool cannot see any other library other than "libdpi.so". I am using few function calls that are present in "libeval.so", and these are not present in "libdpi.so". Is there any switch in gcc, or something to overcome this.

If libdpi.so is designed so that it can open libeval.so, then your program only needs to know about libdpi.so.
Specifically, libdpi.so should have some function that calls dlopen, probably like this:
dlopen("path/to/libdpi.so", RTLD_LAZY);
Then other functions in libdpi.so can interface with libeval.so.
Edit: To build a shared library, use this command:
gcc -shared -o libdpi.so [list of object files to go in libdpi.so]
Note: When you build your objects, use the -fPIC command argument with gcc, like this:
gcc -fPIC -o foo.o foo.c

Related

Calling functions from an external C file that has its own main()

I have two C files, program.c and tests.c, that each contain a main function.
program.c is a standalone program, that compiles and run normally on its own. But I would like to also be able to use some of its functions in tests.c (without using a common header file). Is there a way of doing this?
If I insert the prototype of the function I want from program.c into tests.c and compile with:
gcc -o program.o -c program.c
gcc -o tests.o -c tests.c
gcc -o tests tests.o program.o
I obtain an error duplicate symbol _main, which I understand since there are indeed two `main' functions.
I basically would like to be able to treat program.c both as a standalone program and as a library, similarly to what could be done in Python with if __name__ == '__main__'.
If you need to have two separate distinct executables for which some of the functionality between them is similar you can share the common functionality by placing relevant functions into a third file, and compiling as a portable executable, DLL in Windows. (or shared library in Linux.) Each of these file types contain sharable, executable code, ithout the main() function, designed to be linked during compile time, and dynamically loaded into your executable at runtime.
Here is a step by step set of instructions for shared library using GCC and Linux.
Here is a step by step example for creating DLL using GCC in windows.
So I managed to achieve what I wanted thanks to the comment from #pmg:
I compile program.c into a standalone binary (gcc -o program program.c), but I also compile it into an object file with "main" renamed (gcc -c -Dmain=mainp -o program.o program.c).
I can then use this object file (that does not contain a "main" symbol anymore) to compile tests.c: gcc -o tests tests.c program.o.
Thanks #pmg, I did not know this use of the -D option.

How to write common functions for reusing in C

I was trying to write a common function for other files could reuse it, the example as following, I have three files:
The first file: cat test1.h
void say();
The second file: cat test1.c
void say(){
printf("This is c example!");
}
The third file: cat test2.c
include "test1.h"
void main(){
say();
}
but when I ran: gcc -g -o test2 test2.c
it threw error as:
undefined reference to `say'
Additionally: I knew this would work:gcc -g -o test2 test1.c test2.c
but I don't wanna do this, because the other team would use the server, and I hope them directly use my binary code not source code. I hope that just like we use printf() function, we just need include .
You can build yourself a library from the object files containing your useful functions, and store the header(s) that describe them in a convenient location. You and your colleagues then compile with the headers and link that library with any executables that use any of those functions. That's very much the same general mechanism that the C compiler uses to include the standard headers and automatically link with the standard C library.
The mechanics vary a bit depending on platform (Windows vs Unix being the primary distinction, though there are differences between Unix platforms too), and also on the type of library (static archive vs dynamic linked / loaded libraries — also known as shared objects or shared libraries).
In broad outline, for a Unix system with a static library, you'd:
Compile library object files libfile1.o, libfile2.o, … using (for example) gcc -c libfile1.c libfile2.c.
Create an archive from the object files — using for example ar r libname.a libfile1.o libfile2.o.
Copy the headers to a standard location such as /usr/local/include.
Copy the library to a standard location such as /usr/local/lib.
You'd compile any code that uses the library functions with -I/usr/local/include (if that is not already a standard compilation option).
You'd link the programs with -L/usr/local/lib -lname (you might not need to specify -L… but you would need to specify -lname).
Including a header file does not make a function available. It simply informs the compiler that the function will be provided at a later time.
You should compile the file with the function into a shareable object file (or a library if there is more than one function that you want to share). Mind the switch -c which tells gcc not to build an executable file:
gcc -o test1.o test1.c -c
Similarly, compile the main function into its own object file. Now you or anyone else can link the object file with their main program:
gcc -o test2 test2.o test1.o
The process can be automated using make.
Other programmers can use compiled object files (`*.o') in their programs. They need only to have a header file with function prototypes, extern data declarations and type definitions.
You can also wrap many object files into the library.
On many systems you can also create the dynamic linked libraries which do not have to be linked into the executable.
you also need to compile test1:
gcc -g -o test2 test1.c test2.c.

How to compile ffmpeg.c into shared library?

Is it possible to compile ffmpeg.c into the shared library? I need it in shared library form to link with my C program and call main function in ffmpeg.c.
Yes, it is possible. To do so you'd need to:
Find out how you gonna pass the arguments (if via argc/argv no changes would be needed)
Rebuild the object files linked into ffmpeg shared library with -fpic
Pass the -shared option to the linker

How to link and compile with .so file in Linux

I am having .c and .so file. I tried by using the following compilation: gcc main.c -ldl. In that .c file i linked to .so file through dlsym(). How to compile using .so file with .c.
Probably you can do this:
when linking do:
g++ -o prog prog.o -ldllname
If libdllname.so is not in the system directory then add its directory to the library path:
g++ -o prog prog.o -L/path/to/my/library/folder -ldllname
This is based on your further comments. First guard the declarations of your header file.
#ifndef HEADER_PROTECT
#define HEADER_PROTECT
---------- Here is the content of header
#endif
Next, check in your code, are you defining multiple definitions. Or are you re-defining the standard functions again? Can you please post your code to guide you better?
Looks like you have re-defined Close_Comm(), can you check it? Error says that the definition is there in main.c also.
The following is the general way to compile shared object and link it.
To compile shared objects.
-g : for debug information
fPIC: for position independent code
$gcc -fPIC -g myfile
The following will create the shared object libmyfile.so
$gcc -shared -o libymyfile.so myfile.o
Now,In order to link it with your main.c.
I assume that the libmyfile.so is in your current path, thus -L./
$gcc main.c -o main.out -L./ -lmyfile
Now, you need to export the LD_LIBRARY_PATH on the bash; in order to execute the binary.
$LD_LIBRARAY_PATH=$LD_LIBRARAY_PATH:./
$./main.out
The dlsym is to load the symbol from the shared object at the run-time. If you want to load the shared object at run time, this can be used. The following is one of the example of dlsym Hack the standard function in library and call the native library function afterwards
dlsym() is used to find a symbol in an open library file.
you first need to use dlopen() in order to open the file, and only then use dlsym()

Can I mix static and shared-object libraries when linking?

I have a C project that produces ten executables, all of which I would like to be linked in statically. The problem I am facing is that one of these executables uses a 3rd-party library of which only the shared-object version is available.
If I pass the -static flag to gcc, ld will error saying it can't find the library in question (I presume it's looking for the .a version) and the executable will not be built. Ideally, I would like to be able to tell 'ld' to statically link as much as it can and fail over to the shared object library if a static library cannot be found.
In the interium I tried something like gcc -static -lib1 -lib2 -shared -lib3rdparty foo.c -o foo.exe in hopes that 'ld' would statically link in lib1 and lib2 but only have a run-time dependence on lib3rdparty. Unfortunatly, this did not work as I intended; instead the -shared flag overwrote the -static flag and everything was compiled as shared-objects.
Is statically linking an all-or-nothing deal, or is there some way I can mix and match?
Looking at this thread you can see that it can be done. The guys at GNU suggest
gcc foo.c -Wl,-Bstatic -lbar -lbaz -lqux -Wl,-Bdynamic -lcorge -o foo.exe

Resources