linux環境下的c++ 動態庫的呼叫
主要是為了平時的學習記錄,不妥的地方,煩請指點。
一.下面主要是dlopen開啟動態庫.so相關的API介面函式。
1. void* dlopen(const char* filename,int flag);
filename 是動態庫的path路徑,flag是動態庫載入的幾種方法。
RTLD_LAZY:dlopen返回前,對動態庫中存在的未定義的變數不進行解析,只對函式符號有效,變數符號會被立即載入。
RTLD_NOW: 需要在dlopen返回前,解析出所有未定義符號,如果解析不出來,dlopen時會返回NULL,提示error資訊: undefined symbol: xxxx.......
RTLD_GLOBAL:這個庫中的符號可以被隨後的動態庫使用。
2. char* dlerror(void)
返回相關的錯誤,如果從初始化到最後結束都沒有錯誤,則返回NULL。
3. void * dlsym(void* handle,const char* symbol);
返回符號為symbol的函式的地址,需要用到dlopen中返回的handle,需要使用dlerror來判斷是否是錯誤,
二.下面舉個簡單的例子說明下。
定義一個基類CTestDL,test()和print() 都是純虛擬函式。C++支援了名稱空間、類以及過載等機制,所以符號的命名規則和C不同。而dl API屬於C的部分,使用的C的命名規則,所以在實現上述兩個函式時(也就是說需要通過動態連結的C++函式)需要使用C的符號命名規則。這需要實現extern 'C'實現。
#ifndef __CTEST_DL_H__ #define __CTEST_DL_H__ class CTestDL { public: CTestDL(int a,int b) { length =a; width =b; } virtual ~ CTestDL() { } public: virtual void test(const char*) =0; virtual void print()=0; protected: int length; int width; }; extern "C" CTestDL* GetClass(int,int); //匯出函式名 #endif
下面是一個派生類Test,繼承上面的基類
#include <iostream>
#include "ctest.h"
using namespace std;
class Test :public CTestDL
{
public:
Test(int a,int b):CTestDL(a,b) //虛基類已經賦值了
{
length = a;
width = b;
}
~Test(){}
public:
void test(const char*);
void print();
private:
int length ;
int width;
};
Test類的cpp檔案:
#include <iostream>
#include <stdio.h>
#include "test.h"
using namespace std;
CTestDL* GetClass(int a,int b)
{
return new Test(a,b);
}
void Test::test(const char* data)
{
cout << "--this is a test program !--" <<"**: "<< data << endl;
}
void Test::print()
{
int area = length * width;
cout << "**** the area is **** :" << area << endl;
}
編譯的命令: g++ -shared -lc -s -o libtdlc.so test.cpp -fPIC 生成動態庫libtdlc.so
測試程式:
#include <stdio.h>
#include <unistd.h>
#include <dlfcn.h>
#include <iostream>
#include "ctest.h"
using namespace std;
typedef CTestDL* (*pTestDLObj)(int,int); //定義一個函式指標
int main(int argc,char* argv[])
{
//CTestDL *(*pTestDLObj)(int,int);
dlerror();
void *lib_dl = dlopen("./libtdlc.so",RTLD_LAZY);
if(NULL == lib_dl)
{
printf("load library libtdlc.so error.\nErrmsg:%s\n",dlerror());
return -1;
}
//pTestDLObj = (CTestDL * (*)(int,int))dlsym(lib_dl,"GetClass");
pTestDLObj create_class = (pTestDLObj)dlsym(lib_dl,"GetClass");
const char *dlmsg = dlerror();
if(NULL != dlmsg)
{
printf("get class testdl error\nErrmsg:%s\n",dlmsg);
dlclose(lib_dl);
return -1;
}
//CTestDL *pTestdl = pTestDLObj(2,3);
//CTestDL *pTestdl = (*pTestDLObj)();
CTestDL* tmp = create_class(3,3);
tmp->print();
tmp->test("success full !");
//pTestdl->print();
//pTestdl->test("success full ");
delete tmp;
dlclose(lib_dl);
return 0;
}
編譯: g++ main.cpp -rdynamic -ldl -s -o dl_main
程式執行的結果:
相關推薦
[轉載總結]Linux環境下C++運行時動態鏈接庫加載要點總結
typedef symbol 類的方法 cout use per 解析 轉換 type 最近在看的一些web服務器源碼的擴展部分基本上都使用到了.so動態庫的運行時加載,也遇到了不少坑,看了不少網上的博客,在這裏稍微總結轉載一下,也是為了以後少走彎路。 首先需要了解的就是靜
windows 下C++動態庫的封裝以及呼叫
1、一個程式從原始檔編譯生成可執行檔案的步驟:預編譯 --> 編譯 --> 彙編 --> 連結(1)預編譯,即預處理,主要處理在原始碼檔案中以“#”開始的預編譯指令,如巨集展開、處理條件編譯指令、處理#include指令等。(2)編譯過程就是把預處理完的檔案進行一系列
Linux環境下c程序的編譯和執行
環境變量 動態 main.c tor direct 環境 沒有 stdlib.h share 1 單個文件的編譯和執行創建main.c文件,內容如下: #include <stdio.h> #include <stdlib.h> int main
Linux環境下c程式的編譯和執行
1 單個檔案的編譯和執行建立main.c檔案,內容如下: #include <stdio.h> #include <stdlib.h> int main(void){ printf("Hello world!\n"); return 0; }; 編譯:
windows 下C++動態庫的封裝以及調用
文件鏈接 系列 語義分析 ++ 動態鏈接 中大 動態 turn 應用 1、一個程序從源文件編譯生成可執行文件的步驟:預編譯 --> 編譯 --> 匯編 --> 鏈接(1)預編譯,即預處理,主要處理在源代碼文件中以“#”開始的預編譯指令,如宏展開、處理條
linux環境下給BOOST庫編譯靜態庫加上-fPIC選項
在linux環境下,使用靜態方式編譯boost時,bjam沒有新增-fPIC, 解決辦法如下: 編輯tools/build/v2/tools/gcc.jam檔案,將第391行的 if( $link ) = shared 註釋掉,如下圖:
關於如何在linux環境下生成a庫和so庫(改,附圖)
一般linux環境下的連結庫分為a庫和so庫,分別表示靜態連結庫和動態連結庫,其作用是把C程式編譯好做成一種可執行連結檔案,c主程式檔案呼叫這些程式的函式介面是可以使用a庫或so庫,在主程式中只需要i
linux 環境下 c語言實現mysql資料庫圖片的儲存以及多資料庫直接的轉存
作為一個程式設計師,CSDN對我的程式設計帶來了很多幫助和提高,在這裡可以讓你找到很多開發過程中遇到的問題的解決辦法,今天也寫點自己積累的東西跟大家分享一下,希望對需要的人有幫助. 資料背景: 之前專案一直使用Oracle資料,最近換工作,公司使用的為
gcc,c++ 動態庫呼叫靜態庫
生成動態庫: 需要的目標檔案得用-fPIC選項生成. 而靜態庫所需的目標檔案可以不用-fPIC選項. 一個應用程式呼叫動態庫, 而這個動態庫其中的函式呼叫某靜態庫時,如何生成應用程式呢? 例: /////// static.h void static_prin
linux環境下 C++效能測試工具 gprof 和gprof2dot
1 簡介 改進應用程式的效能是一項非常耗時耗力的工作,但是究竟程式中是哪些函式消耗掉了大部分執行時間,這通常都不是非常明顯的。GNU 編譯器工具包所提供了一種剖析工具 GNU profiler(gprof)。gprof 可以為 Linux平臺上的程式精確分析效能瓶頸。gprof精確地給出函式被呼叫
Linux 環境下C/C++獲取系統時間 && 每隔500ms迴圈一次程式碼實現
環境:NetBeans IDE 8.2 + 遠端主機Linux 獲取當前系統時間getCurrentTime()程式碼如下: #include<sys/time.h> long getCurrentTime(){ struct timeval tv; gett
Linux環境下C程式設計指南---gcc 編譯器常用的命令列引數一覽
1. gcc -E source_file.c-E,只執行到預編譯。直接輸出預編譯結果。2. gcc -S source_file.c -S,只執行到原始碼到彙編程式碼的轉換,輸出彙編程式碼。3. gcc -c source_file.c-c,只執行到編譯,輸出目標檔案。4. gcc (-E/S/c/) so
linux環境下c++的編寫、除錯以及makefile多檔案連編需要注意的問題
最近剛開始接觸Linux C++,發現其與windows C++有太大的差別。這裡是自己的一些總結,如果有新人看到,希望能夠幫到您。 1、gcc編譯器簡介 生成一個.out需要將原始檔依次進行預處理、
Linux環境下軟體(庫)的更新命令
$ sudo apt-get install/delete package$ sudo apt-get -f install #修復安裝$ sudo apt-get dist-upgrade
linux環境下C語言實現非阻塞方式讀取字串資料的串列埠測試程式,即串列埠工具的編寫
一、前言 1.1 關於串列埠測試工具,網上已經有整合好的應用程式提供大家使用,但其只提供功能介面,內部具體怎麼實現的還需要自己去探索; 1.2 關於串列埠通訊的測試程式在網上已經是數見不鮮,但也不排除很多是直接“參考”別人的(ctrl+c),而且很多程式
linux環境下C語言中sleep的問題
printf預設是輸出到標準輸出,而標準輸出預設使用的是行緩衝。在sleep之前fflush(stdout)強制刷緩衝,或者在程式開始使用setbuf(stdout, NULL)禁用緩衝 當然,假如你有足夠的耐心,大約過幾個小時後,緩衝區終於滿了,你會看到效果的。
.net core linux環境下 數據庫連接超時
client 同步 多個數據庫 cor sqlserver sed log 無法定位 表名 最近遇到了一個很奇葩的問題,我編寫了一個.net core程序讀取多個數據庫數據源,進行數據同步處理。該程序在windows環境下運行完全正常,但在linux環境下運行報異常,提示
linux環境下的c++ 動態庫的呼叫
主要是為了平時的學習記錄,不妥的地方,煩請指點。一.下面主要是dlopen開啟動態庫.so相關的API介面函式。1. void* dlopen(const char* filename,int flag);filename 是動態庫的path路徑,flag是動態庫載入的幾種方
python呼叫C動態庫匯出函式的返回值為指標型別時,在64位python環境下被截斷解決方法
class my_void_p(c_void_p): pass def sslog_create_instance(): #直接指定 restype=c_void_p在64位上還是會發生地址截
linux下python呼叫C++動態庫以及庫函式
C++:首先C++需要編譯成動態共享庫C++程式碼(cpptest.cpp)如下------#include<iostream>using namespace std;extern "C"{//在extern “C”中的函式才能被外部呼叫int test(){