Wednesday, July 12, 2023

shared library (".so") file in C++ in Centos 7 Linux

 ".so" file - "shared object file" i.e. "shared library file" creation in C++ in centos 7 linux. :-
----------------------------------------------------------------------------------------------------

before building ".so" library, build your C++ project for that library, so that we can test working of targeted library file. After successfully testing and seeing proper output and functionality checking, build  library. This way is easier than  directly building ".so" file, because we can not test functionality of ".so" lib file in shared library project. It needs runnable program to test. So first test than build library.


first open codeblocks IDE-> new project -> shared library -> next -> C++ :-

1. prject title   : so-file
2. folder project : /opt/projects/so-file
3. project name   : so-file
4. resulting file name : automated by IDE

This "so" file name will be same as name of "project title ".

Now :-
------

1. remove main.cpp
2. Project -> Build options -> tick on Position Independent Code(-fPIC) -> right tick on it.
3. Have g++ follow the coming C++1y (aka C++14) ISO C++ language standard -> right tick on it.
4. Target x86_64 (64bit) -> right tick on it.
5. new file :-
important point : do not add new class to this project because if you do this,
resultant "so" file header will not be able to added in calling cpp project. For example if you build a so file as "so-file.so" and header file "so-file.h" to call its functionalities. Now you add this shared object and header files in your "so-file.so" calling CPP project. In place where we add header file via "#include" directive, intellisense does not recognize it's header file e.g. "so-file.h" will not be added.
    To get it recognized you need to add as this :-
1. new -> file -> C/C++ header -> next ->
   i. file name with full path :- "so-build-w-class.h"
   ii. Header guard will be generated automatically.
   iii. add file to active project : right tick on both Debug and Release
   
2. new -> file -> C/C++ source -> next -> C++ ->
    i. file name with full path : "so-build-w-class.cpp" - be sure name should be same as header file but extension is ".cpp".
    ii. Add file to active project : right tick on both Debug and Release
    -> finish.
3. project -> properties -> bin/Debug/lib01-so-test-h-s.so
                            bin/Release/lib01-so-test-h-s.so
    here "lib01-so-test-h-s.so" name by default will be "liblib01-so-test-h-s.so"
    you need to change it to from double "liblib..." to single "lib..."
    as from "liblib01-so-test-h-s.so" to "lib01-so-test-h-s.so".
    this "so" file name will be same as name of project name. As here mine project name is : "01-so-test-h-s".
-------------------------------------------------------------------------
Example :-
----------

file : "so-build-w-class.h" :-
------------------------------

#ifndef SO-BUILD-W-CLASS_INCLUDED
#define SO-BUILD-W-CLASS_INCLUDED

class print_one
{
public:
    print_one();
    virtual ~print_one();

    void print();
    void read();

protected:

private:

    int i, j;

};

#endif // SO-BUILD-W-CLASS_INCLUDED
---------------------------------------

File : "so-build-w-class.cpp" :-
--------------------------------
#include "so-build-w-class.h"
#include <iostream>

using std::cout;
using std::cin;
using std::endl;

print_one::print_one()
{
    //ctor
    i = j = 5;
}

print_one::~print_one()
{
    //dtor
}

void print_one::print()
{
    cout << "i = " << i << endl;
    cout << "j = " << j << endl;
}

void print_one::read()
{
    cout << "i = ";
    cin  >> i;
    cout << "j = ";
    cin  >> j;
}


resultant "so" will be generated in folder "Debug" or "Release" with "so" extension.

To get it to include in all projects, this file to be recognized locally (under account of its own user) or globally (for all users account). To do that you can do this :-
    i. add it to local user : gedit -> open -> or "home/<user>/.bash_profile".
        add this : "export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:<path to your so file>"
    ii. add it for all users (globally) :
        1. login as root user
        2. gedit -> open -> /etc/profile" and add following (for example) :-
        export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/oracle/instantclient_11_2:/opt/project/lpi/lpi_headers:/opt/so-files:/opt/so-files/so-file-test-without-class/so-files-wc
 
 here "/opt/so-files/so-file-test-without-class/so-files-wc" is path of shared object file path to shared as globally.
         3. or you can also put in "/usr/lib" or "/usr/lib64/" or "/usr/local/lib/" or "/usr/local/lib64/"

        4. or you can make directory "/usr/lib64/your_dir" and paste it your "so" file.


         this will look this file as globally for all applications.
         But may be name clashing happen.
----------------------------------------------

Now we will call this shared object file in our CPP project :-
--------------------------------------------------------------

1. new -> project -> Console application -> next -> C++ ->
    i. Project title : Calling-CPP-project
    ii. Folder to create project in : give path to project location
    iii. project name and resultant file name : manage it by self.
    iv. finish.
2. Project -> build options ->     
    i. Have g++ follow the coming C++1y (aka C++14) ISO C++ language standard -> right tick on it.
    ii. Target x86_64 (64bit) -> right tick on it.
3. linker settings : add -> 01-so-test-h-s
    here IDE will add this shared object file as : "-l01-so-test-h-s"
    you do not need to add full name - with extension.
4. search directories ->
    i. Compiler -> add -> /opt/so-files/so-file-test-without-class/so-files-wc
        path to header file : in may case path of "so-build-w-class.h".
        you can give here as either absolute or relative path.
    ii. Linker -> add -> /opt/so-files/so-file-test-without-class/so-files-wc
        path to shared object ".so" file :  in may case path of "lib01-so-test-h-s.so"
5. add using include directive of header file :    <so-build-w-class.h>
    if it is not in intellisense "Reparse this project" as : right click on project name and select "Reparse this project". Then try again.
 

// example file : project : calling-cpp :-
------------------------------------------
#include <iostream>

#include <so-build-w-class.h>

using namespace std;

int main()
{
    cout << "Hello world!" << endl;

    print_one p;

    p.print();

    cout << "Ente i and j : " << endl;

    p.read();

    cout << endl;

    p.print();

    return 0;
}
 

output :-


[rahul@C-Client Debug]$ ./calling-cpp
Hello world!
i = 5
j = 5
Ente i and j :
i = 3
j = 4

i = 3
j = 4
[rahul@C-Client Debug]$
   
    NOW THIS IS COMPLETE
------------------------------------------------------------------

No comments:

Post a Comment