|Issue| dlopen ERROR: undefined symbol

我們可以利用 dlopen 載入動態函式庫,然後使用 dlsym 取得裡面的函式來使用。

這兩個方法使用方式可以參考:dlopen&dlsym 用法

有遇到載入失敗,出現:undefined symbol

後面接著一串很像函式名稱的東西。

那時候我猜測是有兩種可能:我函式有問題 (可是 compiler 應該不會過才對),或者,

沒有正確連結?

我使用 nm 去驗證我的想法。

nm 可以列出目標的所有 symbol,看是不是那個函式有在裏面,但有問題?還是那個函式真的沒有在裡面?

在 cmd line 執行:nm -C -D bad_lib.so

就會列出全部的 symbol。其中,-D 指的是察看的對象是動態檔唷!

 

還有一個小工具:ldd 順便介紹一下。

ldd (List Dynamic Dependencies) 可以尋找所使用的函式庫!

執行:ldd (選項) (參數)

就可以列出全部被用到的函式庫啦!

 

ref.

解決 undefined symbol / reference

 

|Issue| 將 .a 包進 .so後,無法使用 .so

Segmentation fault

–whole-archive:可以強制將每個對象包含在生成的共享函式庫裡

所以我把我要包進 .so 的 .a lib 都加上了這個參數

總算可以開啟 .so

*在 static 库中,连接器将停止在第一个符号,即使它是一个弱的,并停止寻找强大的。若要强制它查看所有符号( 就像对动态链接库所做的那样),ld 支持 --whole-archive 选项。

 

ref.

https://ask.helplib.com/others/post_12552910

|Code| Makefile 參數介紹

Makefile 裡面最複雜的就是很多符號以及參數不明白意思。

這邊稍微介紹一下。

跟編譯過程有關:

  • -c:編譯但不進行鏈結,會產生一個跟原始碼相同名字的 .o 檔
  • -O:表示最佳化的程度
  • -g:要包含偵錯資訊

跟連結有關:

  • -l :編譯過程需要一個 library。e.g. -lpthread 表示需要 libpthread.so 函式庫
  • -L:需要鏈結庫外部人家已經寫好的函式的目錄
  • -I : 優先搜尋的 include 檔案路徑

跟包成的目標函式庫有關:

  • -shared:如果目標為動態函式/共享函式庫,一定要加
  • -fPIC:包成動態函式
  • -static:包成靜態函式庫

其他字元:

%.o: %.cpp
g++ -Wall -g -c $^
  • $^:所有的必要條件(%.cpp)
  • $@:工作目標(%.o)
  • %:一個萬用字元,

e.g.:%.o: %.c 這一行,就會知道如果現在的工作目標是 demo.o 的話,就會去找對應的 demo.c

  • $<:第一個必要條件(%.cpp,本例子中只有一個必要條件)

傳遞參數:

  • -Wa : 將選項 (option) 傳給組譯器
  • -wl : 將選項 (option) 傳給連結器

備註:

*編譯不連結,表示只檢查 include 裡有沒有宣告,並不會去相關 lib 找函式真的是否存在

*動態函式跟共享函式差別在於:動態函式程式執行時期並不會去檢查該函式是否存在,而是程式執行到某功能時才進行檢查。

*編譯時,利用 -L 告訴編譯器可以該路徑下尋找 libpthread.so。

若使用了-l,則必須使用的 lib 在預設尋找的目錄中,

保險起見,可以利用 -L 指定多個路徑給編譯器。

ref.

http://maxubuntu.blogspot.com/2010/02/makefile.html

[Linux] 簡單的 Makefile 使用 (% 萬用字元、$@ 特殊符號、.PHONY 假目標)

|Jobs| NB 雙系統 : Ubuntu 回到 Windows 後,時間異常

如果你在一台筆電灌雙系統:ubuntu 及 windows,在切換時,應該會遇到一件事:

從 ubuntu  切回 windows,時間顯示異常。

這是因為 Linux base 系統時間預設是使用 UTC,然後寫進硬體時鐘。

而 windows 是使用 Local 時間存在硬體時鐘裡。

解法:

修改一個註冊檔,讓 windows 跟 ubuntu 一樣,用 UTC 當作計算時間的方法

點兩下這個註冊檔即可:WindowsTimeFixUTC.reg

 

ref. Clock shows wrong time after switching from Ubuntu to Windows 10

 

延伸:What is UTC? What is the Local time ?

|Code| uint8_t vs unsigned char

越底層的程式,就要越善用資源 (空間+時間)

晶片廠的程式碼,很少直接: char 的,因為太浪費空間啦!!!

多半會用:uint8_t 表示 char 的東東

uint8_t = unsigned char

uint8_t 只會占用 8 bit (1 byte)

char 是 -128 ~ 127
unsigned char 是 0 ~ 255
extend ascii 是 0 ~ 255

 

現在 C 語言的寫法建議:

引用 stdint.h 函式庫,並使用具有帶號(signed)與長度資訊宣告方式:

  • 帶正負號的整數使用 int8_tint16_tint32_tint64_t
  • 不帶號的整數使用 uint8_tuint16_tuint32_tuint64_t
  • 32 與 64 位元長的浮點數使用 floatdouble

 

其他整理:

  1. char 可以直接 cast it to uint8_t
  2. uint8_t a = 5; printf(“%d”, a);

 

ref.

2016 年,現代 C 語言的寫法

WordPress.com.

Up ↑