1. 程式人生 > >SO檔案的編寫,編譯,使用方法

SO檔案的編寫,編譯,使用方法

(1)SO檔案簡介

linux下的.so檔案為共享庫,相當於windows下的dll檔案。在系統目錄/usr/lib/下,我們可以看到很多應用程式庫檔案(常用的動態連結庫和軟體包的配置檔案)。

(2)SO檔案編譯方法

A. SO檔案沒有main

我們首先編寫簡單的兩個函式,然後把它編譯成so檔案

int max(int a,int b){
    if(a>b)
        return a;
    else
        return b;
}
int add(int a,int b){
    return a+b;
}

B. makefile檔案編寫

(1)編譯時gcc後加-fPIC,這可以使gcc產生於位置無關的程式碼;
(2)連線時,使用-shared,指示生成一個共享庫檔案;
(3)共享庫檔案一lib開頭+副檔名.so;
makefile檔案如下:

.SUFFIXES:.c .o
CC=gcc
SRCS=test.c
OBJS=$(SRCS:.c=.o)
EXEC=libtest.so
all:$(OBJS)
        $(CC) -shared -o  $(EXEC) $(OBJS)
.c.o:
        $(CC) -Wall -g -fPIC -o $(@) -c $<
clean:
        rm -f $(OBJS)
        rm -f core*

make編譯連結test.c檔案,結果:

xin@xin-Lenovo-V3000:~/code/test1$ ls
makefile  test.c  test.h
xin@xin
-Lenovo-V3000:~/code/test1$ make gcc -Wall -g -fPIC -o test.o -c test.c gcc -shared -o libtest.so test.o xin@xin-Lenovo-V3000:~/code/test1$ ls libtest.so makefile test.c test.h test.o

生成libtest.so檔案。

(3)SO檔案使用方法

(1).bash_profile新增export LD_LIBRARY_PATH=LDLIBRARYPATH:..so/usr/lib/(

)exportLDLIBRARYPATH=LD_LIBRARY_PATH:.是為了,呼叫.so檔案時候於.so檔案位置無關。

# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
       . ~/.bashrc
fi
# User specific environment and startup programs

PATH=$PATH:$HOME/bin:.

export PATH

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.

一定注意拼寫,寶寶曾經犯過一些關於拼寫錯誤,找了很長時間。
然後:wq退出,還要讓.bash_profile生效,輸入語句:

xin@xin-Lenovo-V3000:~$ . .bash_profile

注意:兩個小點之間有一個空格。

(2)在別的c檔案(或者cpp)中使用so檔案,一定要包含so檔案的標頭檔案。
test.h檔案:

#ifndef TEST_H
#define TEST_H
#ifdef __cplusplus
extern "C"{
#endif

int max(int a,int b);
int add(int a,int b);
#ifdef __cplusplus
}
#endif
#endif // TEST_H

這裡採用了混合程式設計,否則g++編譯會發生錯誤。
(3).cpp檔案為:

#include<stdio.h>
#include<stdlib.h>
#include "test.h"
int main(){
    printf("max=%d\n",max(4,5));
    printf("add=%d\n",add(4,5));
    return 0;
}

(4).cpp的makefile檔案編寫:

.SUFFIXES:.cpp .o
CC=g++
SRCS=a.cpp
OBJS=$(SRCS:.cpp=.o)
EXEC=a
start:$(OBJS)
        $(CC) -o $(EXEC) $(OBJS) -L. -ltest
.cpp.o:
        $(CC) -Wall -g -o $(@) -c $<
clean:
        rm -f $(OBJS)
        rm -f core*

其中:g++連結時-L引數指明so檔案存放路徑,-l引數指明so檔名。
(CC)o(EXEC) $(OBJS) -L. -ltest
-L:在當前路徑尋找so檔案;
-ltest:意思為連結libtest.so這個庫檔案;
(5)make結果:

xin@xin-Lenovo-V3000:~$ cd code/test1
xin@xin-Lenovo-V3000:~/code/test1$ make
g++ -Wall -g -o a.o -c a.cpp
g++ -o a a.o -L. -ltest
xin@xin-Lenovo-V3000:~/code/test1$ ls
a  a.cpp  a.o  libtest.so  makefile  test.c  test.h  test.o
xin@xin-Lenovo-V3000:~/code/test1$ ./a
max=5
add=9

如果我們.h檔案不採用混合編譯,而簡單的這樣寫:

#ifndef TEST_H
#define TEST_H
int max(int a,int b);
int add(int a,int b);
#endif // TEST_H

當我們make時候就會:

[email protected]:~/code/test1$ make
g++ -Wall -g -o a.o -c a.cpp
g++ -o a a.o -L. -ltest
a.o:在函式‘main’中:
/home/xin/code/test1/a.cpp:5:對‘max(int, int)’未定義的引用
/home/xin/code/test1/a.cpp:6:對‘add(int, int)’未定義的引用
collect2: error: ld returned 1 exit status
makefile:7: recipe for target 'start' failed
make: *** [start] Error 1

因為我們編寫的.so檔案是c編寫的,如果cpp檔案呼叫,必須用extern “C”關鍵字修飾,表示用c的方法識別這個函式。

相關推薦

SO檔案編寫編譯使用方法

(1)SO檔案簡介 linux下的.so檔案為共享庫,相當於windows下的dll檔案。在系統目錄/usr/lib/下,我們可以看到很多應用程式庫檔案(常用的動態連結庫和軟體包的配置檔案)。 (2)SO檔案編譯方法 A. SO檔案沒有main 我

so庫的反編譯反彙編

Linux APP,SO的反彙編工具, ida Pro,可以反彙編app和SO庫,有函式名,但是不能反編譯到code這一級別。 下載最強的反編譯工具 ida Pro 6.4 Plus.rar  Hopper是一款執行在Mac、Windows和Linux下的除錯(os x

Linux(centos/fedora/redhat/ubuntu....)下如何安裝rpm,deb檔案如何解壓編譯安裝*.tar.gz檔案

RPM格式軟體包的安裝 1.簡介 幾乎所有的Linux發行版本都使用某種形式的軟體包管理安裝、更新和解除安裝軟體。與直接從原始碼安裝相比,軟體包管理易於安裝和解除安裝;易於更新已安裝的軟體包;易於保護配置檔案;易於跟蹤已安裝檔案。 RPM全稱是Red Hat Package Manager(Red Hat

4.前端基於react,後端基於.net core2.0的開發之路(4) 前端打包編譯路由模型服務

hub 解決 路徑 export routes run 部署 service 後端 1.簡要的介紹 學習react,首先學習的就是javascript,然後ES6,接著是jsx,通常來說如果有javascript的基礎,上手非常快,但是真正要搭建一個前端工程化項目,還是有很

實驗三 程式設計編譯連線跟蹤

實驗內容: (1)將下面的程式儲存為t1.asm檔案,將其生成可執行檔案t1.exe assume  cs:codesg codesg  segment       mov  ax , 2000H      

實驗 3 程式設計編譯連線跟蹤

一、實驗目的 1.  掌握組合語言源程式(8086 dos 彙編)編寫→彙編→連結→除錯的方法 2.  加深對 1-4 章基礎知識的理解   二、實驗準備 1. 結合第 4 章課件和教材,學習/複習完整彙編源程式編寫→彙編→連線→執行→除錯

c編輯器之clion安裝編譯控制檯亂碼修復

1. 下載clion,注意安裝的時候選擇的目錄不能有任何中文字型。只能英文+數字 2.安裝完畢後,開啟軟體,選擇License Server,輸入:http://xidea.online 3.啟用完

c語言編譯過程詳解預處理編譯彙編連結(乾貨滿滿)

鍥子 我們在各自的電腦上寫下程式碼,得明白我們程式碼究竟是如何產生的,不想了解1,0什麼的,但這幾個環節必須掌握吧。 我們的程式碼會經過這4個環節,從而形成最終檔案,c語言作為編譯語言,用來向計算機發出指令。讓程式設計師能夠準確地定義計算機所需要使用的資料,並精確地定義在

Spark on yarn Intellij ide 安裝編譯打包叢集執行 詳解

說明:已經安裝好hadoop2.2.0 完全分佈,scala,spark已安裝好,環境配置完畢;主機為hadoop-master,hadoop-slave 一.intellij 安裝(centos6.5系統) 步驟一。 1.將上述兩個安裝

修改編譯GDB除錯openjdk8原始碼(docker環境下)

在上一章《在docker上編譯openjdk8》裡,我們在docker容器內成功編譯了openjdk8的原始碼,有沒有讀者朋友產生過這個念頭:“能不能修改openjdk原始碼,構建一個與眾不同的jdk“,今天我們就來閱讀一些openjdk的原始碼,再嘗試做些小改

php_screw安裝使用編譯問題說明

安裝步驟: 1. 下載原始碼:wget http://nchc.dl.sourceforge.net/project/php-screw/php-screw/1.5/php_screw-1.5.tar.gz 2. 解壓縮:tar zxvf php_screw-1.5.t

深入理解預編譯編譯彙編連結的過程——之編譯和使用(連結)庫——物件和靜態庫

當你完成了程式碼開發,想把這個程式碼給別人用,但是又不希望別人看到原始碼,就要給別人一個庫和標頭檔案,庫和標頭檔案是配合的,缺一不可。 或者過程相反,你從別人那裡拿到一個庫和標頭檔案來使用。 那麼如何編譯生成一個庫給他人,如何使用從他人那裡拿到的庫呢? 範例1:我們想把Li

程式的生成過程預處理編譯彙編連結

當我們使用VS或者其他編譯器對我們所寫的程式進行執行時,在下面會出現,編譯、連結等等顯示,那麼到底什麼是編譯,連結?我們所寫的程式碼到底是怎樣變成可執行程式的?接下來就為大家解釋,程式是如何產生的。 示例一個大家都見過的程式列印:hello world!(檔名

eric6+pyqt5,修改UI檔案後重新編譯方法

新手在用ERIC6+PYQT5的時候重新修改了UI檔案,卻找不到重新編譯的地方,網上也沒有現成的答案,這兒介紹一下過程:1,開啟ERIC62,在ERIC6介面最右邊找到QT-DESIGNER圖示,並開啟3,在QT-DESIGNER介面下,左上角,檔案->開啟要修改的UI

Linux下的.so檔案編寫

Linux下的.so是基於linux下的動態連結,其功能和作用類似與windows下.dll檔案。 下面是關於.so的介紹: 一、引言 通常情況下,對函式庫的連結是放在編譯時期(compile time)完成的。所有相關的物件檔案(object file)與牽涉到的

Eclipse開發編譯打包常見問題總結------持續更新

fig 打jar jdk版本 -a 客戶 找到 找不到 color spa 在使用Eclipse開發,編譯,打包常見問題如下: 1、 保證本地開發的客戶端與服務端使用的jdk版本一致 2、 保證本地開發的客戶端與服務端使用的依賴jar包版本一致(比如本地thrift

c編譯呼叫動態連線庫 (.so檔案)

c編譯,呼叫動態連線庫 (.so檔案) C編譯: 動態連線庫 (.so檔案) Linux動態連結庫.so檔案的命名及用途總結 Linux程式設計練習(二)—— Linux下.so動態庫的建立和呼叫 在“紙上談兵: 演算法與資料結構”中,我在每一篇都會有一個C程式,用於實現演算法和資料

linux下gcc編譯 .c檔案生成動態連結庫 .so檔案並測試呼叫該連結庫

簡單介紹:linux中so檔案為共享庫,和windows下dll相似;so可以共多個程序呼叫,不同程序呼叫同一個so檔案,所使用so檔案不同;so原檔案不需要main函式;例項,1.通過mysqlTest.c中的函式mysql(),生成一個libmysql.so連結庫#inc

.Net Core 2.0 程式 編譯出exe可執行檔案方法

.Net Core 2.0 程式 用vs生成後無exe啟動項,如果需要生成exe執行檔案可以: 1.修改專案的csproj檔案內容 原始: <PropertyGroup> <OutputType>Exe</OutputType> <

靜態庫資原始檔、xib、圖片打包處理編譯生成的靜態庫.a包檔案太大縮小解決方法

給自己做個標記,詳情請訪問以下地址,親測過,沒問題的 另外,編譯生成的.a檔案太大,但又沒有冗餘的檔案可以刪除已減少體積,找了很久才找到解決辦法,如下: Build Settings-->Generate Debug Symbols將值設為NO