C語言動態庫libxxx.so的幾種使用方法

Koma_Wong發表於2018-08-26

首先先編寫一個簡單的函式func.h func.c

func.h

#ifndef _FUNC_H
#define _FUNC_H

#include <stdio.h>
#include <stdlib.h>

void fun(char *str);

#endif

func.c

#include <func.h>

void fun(char *str)
{
	printf("%s\n", str);
	
}

將這個函式編譯成動態庫

$ gcc func.c -I . -shared -fPIC -o libfunc.so
$ ls
func.c*  func.h*  libfunc.so*  main.c*

編寫main.c程式

#include <func.h>

int main(int argc, char *argv[])
{
	fun("Hello World!\n");
	
	return 0;
}

編譯方法一:

$ gcc main.c -I . ./libfunc.so
$ ./a.exe
Hello World!

檢視可執行檔案依賴:

$ ldd a.exe
        ntdll.dll => /cygdrive/c/Windows/SYSTEM32/ntdll.dll (0x77d20000)
        KERNEL32.DLL => /cygdrive/c/Windows/System32/KERNEL32.DLL (0x779b0000)
        KERNEL32.DLL => /cygdrive/c/Windows/System32/KERNEL32.DLL (0x779b0000)
        KERNELBASE.dll => /cygdrive/c/Windows/System32/KERNELBASE.dll (0x74e40000)
        libfunc.so => /home/rongtao/libfunc.so (0x690c0000)
        cygwin1.dll => /usr/bin/cygwin1.dll (0x61000000)

裡面依賴的dll檔案是因為我用的cywin,是windows下面的Linux模擬軟體,所以會用到,我們主要關注這個libfunc.so庫檔案,關注它後面的路徑,可以看到這個地方的路徑即為編譯時的路徑。

我們再看看這個動態庫內部的函式關係:

$ nm libfunc.so | grep T --color=auto
690c1690 T ___CTOR_LIST__
690c1104 T ___cxa_atexit
690c169c T ___DTOR_LIST__
690c10c0 T ___gcc_deregister_frame
690c1000 T ___gcc_register_frame
690c3264 R ___RUNTIME_PSEUDO_RELOC_LIST__
690c3264 R ___RUNTIME_PSEUDO_RELOC_LIST_END__
690c1690 T __CTOR_LIST__
690c12d0 T __cygwin_crt0_common@8
690c1150 T __cygwin_dll_entry@12
690c1250 T __cygwin_noncygwin_dll_entry@12

nm指令是檢視庫檔案的宣告、未宣告的函式等作用。在程式設計過程中我們經常會遇到“未引用的定義”,這個其實就可以用nm命令檢視。在這裡我想說個題外話,訊息佇列的庫是“-lrt”,之前編譯的N多變沒通過的原因就是沒加這個庫。

編譯方法二:

如果我們把這個檔案家內的libfunc.so檔案刪除,再執行可執行檔案會出現如下錯誤:

$ ls
a.exe*  func.c*  func.h*  main.c*

$ ./a.exe
D:/Program Files (x86)/cygwin/home/rongtao/a.exe: error while loading shared libraries: libfunc.so: cannot open shared object file: No such file or directory

無法載入動態庫檔案。

這裡我用的cywin,所以說和一般的Linux系統不一樣,沒法演示,具體流程是:

如果系統是x86_64的,那麼在/usr/lib64資料夾下為系統庫,這個庫是可以直接呼叫的(例如我們的-lm, -pthread,-lrt等),如果我們將動態庫檔案放到這個資料夾下就可以直接用“-lfunc”來呼叫。此處不做過多講解。

相關文章