welcom ! Handel home

顯示具有 python 標籤的文章。 顯示所有文章
顯示具有 python 標籤的文章。 顯示所有文章

2025年4月10日 星期四

RTOS 虛擬平台 (VM) 軟體系統架構規劃草案

 

📘 RTOS 虛擬平台 (VM) 軟體系統架構規劃草案


🧠 設計核心理念

  1. 語言選擇需具跨平台性與延續性

    • 建議語言:C/C++ 為底層核心語言、Python/Lua 作為上層測試或配置介面語言。

    • 語言延續性確保「知識經驗」不歸零、支援平台轉換。

  2. 重視軟體靈魂——資料結構、狀態圖與演算法設計

    • 導入 UML / Statechart / Flowchart 工具輔助分析。

    • 採標準化文檔格式(如 Markdown + PlantUML 或 Doxygen)建構文件與設計庫。

  3. 建構跨平台可重用的函數庫(Library)架構

    • 函數庫需以功能導向與需求導向為核心。

    • 移植平台時只需重新撰寫 L01~L03 層的實作即可,其餘層維持共通。


🏗️ 軟體系統分層架構

以下為推薦的 8 層虛擬平台軟體架構模型:

層級名稱功能說明可連接層
L00HardHDL實體硬體模擬層,平台抽象化支援 FPGA/MCU/ARM 等
L01BIOS最低階 I/O 初始化與啟動例程,如 clock, gpio, uartL00
L02DRIVE1_LOW基礎外設驅動,如 Timer、ADC、PWM、I2C、SPIL01, L00
L03DRIVE2_HIGH高階驅動層,封裝 sensor、motor、CAN、LCD、FlashL02, L01
L04SYS_PUBLIB系統級公用函式:RTOS抽象層、記憶體池、佇列封裝、錯誤處理L03, L02
L05APP_PUBLIB應用共用邏輯層:演算法、數學函數、座標轉換、通訊協定封裝L04, L03
L06USER_PUBLIB使用者應用函式封裝,如 control策略、任務流程模組L05, L04
L07APP實際應用程式(如自走車、機器手臂、數據採集)L06, L05, L04

🔗 嚴格層級依賴限制(LINK規範)

  • 上層僅可呼叫指定下層,反向依賴禁止

    nginx
    L07 → L06, L05, L04 L06 → L05, L04 L05 → L04, L03 L04 → L03, L02 L03 → L02, L01 L02 → L01, L00 L01 → L00



📦 技術配套工具建議

類型工具建議
文件生成DoxygenSphinxMkDocs
圖示建模PlantUMLDraw.ioyEd
設計追蹤Markdown + Git 管理技術資源庫
單元測試Unity for C, pytest for Python
VM 平台模擬QEMU、自訂 HAL/Driver layer 做 mock 驗證
自動編譯系統CMake + Makefile + NinjaPlatformIO

🧰 可進一步建構:

  • 📁 vm_sys/:儲存虛擬硬體資源模組

  • 📁 libs/:依照 L01~L06 結構分層建置

  • 📁 app/:各應用模組 (如 BLE、AGV、LineFollower)

  • 📁 doc/:UML + API 說明文件,版本控管

  • 📁 tool/:交叉編譯腳本、模擬驅動、測試平台工具


🔚 小結與後續建議

這套分層 VM 架構:

  • 可模擬 RTOS 開發、支援軟體重構與平台移植

  • 適用於教育用途、快速原型、內部開發平台統一

📌 下一步建議

  • 依此模型實作出一個 demo 架構(例如以 FreeRTOS + STM32 為範本)

  • 可建立 L01~L03 的 HAL 測試模擬框架(Mock HAL)


Python 中使用 class 建立物件的優缺點

 在 Python 中使用 class 建構物件(Object-Oriented Programming,OOP)是一種非常常見且強大的編程模式。以下是它的優缺點整理與說明,並附上實務角度的應用建議 👇


🧱 Python 中使用 class 建立物件的優缺點


✅ 優點(Advantages)

優點說明
🧩 結構清晰、模組化class 將資料與邏輯封裝成單元,讓專案結構更清楚。
🔁 可重用性高同一個類別可建立多個物件實例,程式重複使用性強。
📦 封裝性(Encapsulation)類別可以把變數、函式都包在一起,方便管理與擴充。
👨‍👨‍👧‍👦 支援繼承可定義父類別與子類別,延伸功能不用重寫程式。
🧠 更貼近人類思考邏輯模擬「現實世界物件」概念,對大型系統更好維護。
⚙️ 可使用魔法方法__str__, __init__, __len__ 等,可客製行為(像運算子重載)。
✅ 易與框架整合主流框架如 Django、Flask、PyTorch 都大量使用類別封裝模型與邏輯。

❌ 缺點(Disadvantages)

缺點說明
⏳ 開發初期較複雜小專案或腳本使用 class 反而多餘,增加學習曲線。
🔍 Debug 較難出現 bug 時需要追蹤 self、繼承與方法覆蓋,複雜度提升。
🚫 執行效率略低相較於純函式或腳本式寫法,物件導向建立與呼叫物件略有額外開銷。
🧪 濫用設計模式易過度工程初學者可能誤用繼承或設計模式,使簡單功能變複雜。
🔁 多層繼承不易閱讀若設計不良,多層繼承與方法覆蓋會降低程式可讀性與可維護性。

🧪 範例比較

1️⃣ 非類別版本(簡單腳本):

python
def area(radius): return 3.14 * radius ** 2 print(area(5))

2️⃣ 使用類別版本:

python
class Circle: def __init__(self, radius): self.radius = radius def area(self): return 3.14 * self.radius ** 2 c = Circle(5) print(c.area())

🟢 當功能需求增加(如加 perimeter、change radius),class 版本的擴充性就會明顯優於函式版本。


🔧 適合使用 class 的情境

情境說明
需要表示「物件」或「實體」如:車、使用者、帳戶、商品等,天然適合用 class 封裝。
需要多個相似物件建立多個物件如多個 sensor、button、AI 模型等。
需要封裝邏輯與狀態如 GUI 組件、遊戲角色、資料庫連線物件等。
開發中大型專案使用物件導向有助於模組化、團隊合作與維護。

📝 小結建議

類型建議
🟢 中大型專案✅ 建議用 class 實作模組與元件
🟡 小腳本工具🚫 class 可能多此一舉,函式即可
🔁 重複使用邏輯✅ 用 class 封裝邏輯與狀態管理
📦 組件式架構(GUI / AI 模型 / API)class 非常合適,支援擴充與繼承

python code .exe 執行速度會比 .py 快嗎?

 


.exe 執行速度會比 .py 快嗎?

🔍 簡短答案:

大部分情況下不會更快,甚至 有時會慢一點


🔬 為什麼?深入分析:

1️⃣ .exe 還是執行 Python Bytecode(不是原生機器碼)

即使你用 pyinstallercx_Freeze 等工具打包 .py → .exe

  • .exe 裡其實是包含:

    • Python 解譯器(如 python39.dll

    • 你原始的 .pyc.py 檔案

  • 本質上 仍然是由 Python 虛擬機器去執行位元組碼

🚫 所以它並沒有像 C/C++ 編譯成 native code 那樣的效能提升。


2️⃣ 有些情況會變慢

.py

  • 直接用現有的 Python 解譯器執行

  • 不需要解壓縮內嵌的檔案

.exe

  • 開始執行時,會花時間:

    • 解壓縮 embedded modules

    • 初始化 Python runtime

    • 掃描 runtime dependencies

🔍 所以執行前的「啟動時間」可能 稍微變慢,尤其是第一次開啟時。


🧪 速度測試範例

以下是常見的測試結果(根據社群與實測):

測試內容.py.exe (pyinstaller -F)
小程式啟動速度0.1 秒0.5 ~ 1.5 秒
算法邏輯執行幾乎相同幾乎相同
GUI 初始化差不多差不多

🚀 什麼情況才會變快?

✅ 使用 NuitkaCython 這類工具

這類工具會把 .py 編譯成 C 語言,再編譯成 native .exe,速度才會真正提升!

bash
# Nuitka 範例 nuitka --standalone your_script.py

效能最多可提升 1.5x~5x(依照演算法密集程度)


📦 小結整理

問題答案
.exe.py 快嗎?❌ 多數情況下不會更快,只是打包整合方便
有什麼優點?✅ 可免安裝 Python、隱藏程式碼、方便部署
什麼才會真的變快?✅ 使用 Nuitka、Cython 編譯成 C 再轉 native code
打包後會慢嗎?❗ 啟動初期可能略慢,但主程式效能一致

如果你有高效能需求(例如數值模擬、AI 推論、影像處理),可以轉用:

  • 👉 Cython 加速模組

  • 👉 Nuitka 完整 native 打包

  • 👉 Numba JIT 加速


Python .py 編譯成 .exe 的 優點與缺點分析

 

🐍 Python .py 編譯成 .exe優點與缺點分析


✅ 優點(Pros)

優點說明
✔️ 可執行檔 (不需裝 Python)使用者只要下載 .exe 就能執行,不必安裝 Python 環境。
✔️ 原始碼隱藏.py 被打包後難以還原原始碼(雖非絕對安全),提升保護程度。
✔️ 可打包成單一檔案使用 pyinstaller -F 可將整個程式變成一個可攜式檔案,方便分發。
✔️ 避免套件相容性問題所有依賴都可一起打包進去,不受目標機器環境影響。
✔️ GUI 程式更專業使用 -w 參數可讓 GUI 程式不跳出黑框命令視窗。
✔️ 支援加圖示、資源檔、版本資訊可加上 .ico、manifest、license 等使程式更完整。

❌ 缺點(Cons)

缺點說明
❗ 產出檔案很大一般最少 10~50 MB,包含 Python 解譯器與模組。
❗ 打包速度較慢打包大型應用時時間可能很久,甚至幾分鐘以上。
❗ 有些模組不支援打包某些特殊模組(如 tkinter.ttk, asyncio subprocess)在打包時需特殊處理。
❗ 難以跨平台Windows 打包只能在 Windows 上跑,Linux 要用 Linux 打包。
❗ 仍可能被反編譯雖然難度比 .py 高,但 .exe 中的 bytecode 還是可能被解出來。
❗ 依賴管理較不靈活打包後無法像 pip install 那樣動態加套件。

🎯 適合用 .exe 編譯的情境

適用情境說明
提供給非技術使用者使用者不會安裝 Python,只要雙擊執行即可。
商業軟體發佈原始碼不可公開,需一定程度保護。
GUI 應用工具如 tkinter、PyQt 應用,適合以 .exe 方式釋出。
單檔攜帶式工具例如:小工具、日常助手、內部用的 utility script。

🛠 常見打包工具比較

工具特點適合對象
pyinstaller最常用、支援多平台、可打包單檔一般用戶最推薦
cx_Freeze可客製 setup.py,控制更細緻進階用戶
nuitka將 Python 轉 C,再編譯成執行檔(執行效能提升)效能敏感型專案
auto-py-to-exe有 GUI 的 pyinstaller 前端GUI 用戶友善

🔚 小結

條件建議
需要提供給外部使用者或公司內部非開發人員👍 建議打包成 .exe
是 CLI 或 GUI 工具、包含多個模組、資源檔👍 可整合進 .exe
只是測試或內部開發用🟡 無需打包,直接 .py + venv 執行即可
有絕對安全需求.exe 無法 100% 防反編譯,建議考慮 C 擴充或加密混淆方案


py_compile 和 compileall

 py_compilecompileall 是 Python 標準庫中用於將 Python 原始碼(.py 檔案)編譯成位元組碼(.pyc 檔案)的模組。以下是對這兩個模組的詳細說明:

py_compile 模組

  • py_compile 模組提供了一個函數 compile(),用於將單個 Python 原始碼檔案編譯成位元組碼檔案。
  • 主要用途:
    • 在安裝共享模組時,對於那些使用者可能沒有權限在包含原始碼的目錄中寫入位元組碼快取檔案的情況,這個函數非常有用。
    • 手動編譯單一.py檔案。
  • py_compile.compile(file, cfile=None, dfile=None, doraise=False, optimize=-1, invalidation_mode=PycInvalidationMode.TIMESTAMP, quiet=0)
    • file:要編譯的原始碼檔案的路徑。
    • cfile:編譯後的位元組碼檔案的路徑。如果未指定,則預設路徑為 __pycache__ 目錄中的一個檔案。
    • dfile:錯誤訊息將使用的源檔案名稱。
    • doraise:如果為 True,則在編譯錯誤時引發 py_compile.PyCompileError。如果為 False(預設值),則將錯誤寫入 sys.stderr
    • optimize:控制優化級別,並傳遞給內建的 compile() 函數。
    • invalidation_mode:指定位元組碼快取失效模式。
    • quiet:控制錯誤訊息的處理方式。
  • py_compile模組可以作為腳本調用,編譯多個源檔案。

compileall 模組

  • compileall 模組提供了一些函數,用於遞迴地將一個目錄樹中的所有 Python 原始碼檔案編譯成位元組碼檔案。
  • 主要用途:
    • 在安裝 Python 庫時,用於建立快取的位元組碼檔案,以便沒有庫目錄寫入權限的使用者也可以使用。
    • 編譯資料夾內所有的.py檔案。
  • compileall.compile_dir(dir, maxlevels=None, ddir=None, force=False, rx=None, quiet=False, legacy=False, optimize=-1, invalidation_mode=PycInvalidationMode.TIMESTAMP, workers=1, limit=None, hash_based=None, skip_curdir=True, exclude_dirs=[], include_dirs=[], callback=None)
    • dir:要遞迴編譯的目錄的路徑。
    • 其他引數:控制編譯過程的各個方面,例如遞迴深度、強制重新編譯、排除或包含特定檔案等。
  • compileall模組也可作為腳本調用,編譯指定目錄下的所有檔案。

總結

  • py_compile 用於編譯單個檔案。
  • compileall 用於編譯整個目錄樹中的檔案。
  • 這兩個模組都可用於提高 Python 程式的載入速度,特別是在部署共享模組時。

一鍵 .py → .pyc 編譯工具(GUI 版本)

 這裡是 GUI 版本的一鍵 .py → .pyc 編譯工具,使用 tkinter 製作簡單介面,讓你可以點選資料夾後自動編譯所有 .py 檔案。


🖼️ GUI 版一鍵 .py 編譯器(使用 compileall

📄 pyc_gui_compiler.py

python
import tkinter as tk from tkinter import filedialog, messagebox import compileall import os def select_folder(): folder_path = filedialog.askdirectory() if not folder_path: return result = compileall.compile_dir(folder_path, force=True) if result: messagebox.showinfo("完成", f"✅ 已成功編譯:\n{folder_path}") else: messagebox.showerror("錯誤", f"❌ 編譯失敗,請檢查檔案內容\n{folder_path}") # 建立視窗 root = tk.Tk() root.title("Python 一鍵 .py → .pyc 編譯器") root.geometry("400x200") root.resizable(False, False) label = tk.Label(root, text="請選擇含有 Python 程式碼的資料夾", font=("Arial", 12)) label.pack(pady=20) button = tk.Button(root, text="選擇資料夾並開始編譯", command=select_folder, font=("Arial", 12), bg="#4CAF50", fg="white") button.pack(pady=10) footer = tk.Label(root, text="By ChatGPT|使用 compileall 編譯", font=("Arial", 9), fg="gray") footer.pack(side="bottom", pady=10) root.mainloop()

✅ 使用方式

1. 儲存上面程式為 pyc_gui_compiler.py

2. 執行:

bash
python pyc_gui_compiler.py

3. 點選資料夾,即會自動編譯裡面的 .py 檔案成 .pyc


🚀 若想打包成獨立 EXE(不需裝 Python)

pyinstaller 打包:

bash
pyinstaller -F -w pyc_gui_compiler.py
  • -F:打包成單一 EXE

  • -w:不顯示命令列視窗(適合 GUI)

產出後你會在 dist/pyc_gui_compiler.exe 找到它!



Python 專案結構(py ,pyc,exe ) CLI 範例

 

  1. ✅ 範例 Python 專案結構

  2. 🧰 py → pyc 一鍵編譯腳本(單檔 & 整個資料夾)

  3. 🧱 pyinstaller 打包範例(CLI 與 GUI)


✅ 1. 範例專案結構

這是你的一個簡單 Python 專案結構:

arduino
my_project/ ├── main.py ├── utils.py ├── config/ │ └── settings.py ├── modules/ │ ├── mathlib.py │ └── strlib.py └── compile_all.py ← 工具:一鍵編譯 .py → .pyc

🧰 2. compile_all.py:一鍵將專案中所有 .py 轉成 .pyc

python
# compile_all.py import compileall import os # 自動取得當前目錄 project_dir = os.path.dirname(os.path.abspath(__file__)) print(f"🔧 正在編譯:{project_dir}") success = compileall.compile_dir(project_dir, force=True) if success: print("✅ 所有 .py 檔案已成功編譯為 .pyc") else: print("❌ 編譯時發生錯誤,請檢查原始碼")

📌 使用方法:

bash
python compile_all.py
  • 會遞迴編譯所有子目錄 .py 檔,產生 .pyc__pycache__/ 中。


🧱 3. 打包成 EXE:使用 pyinstaller

📦 安裝 PyInstaller

bash
pip install pyinstaller

🛠️ CLI 工具打包(有命令列視窗)

bash
pyinstaller -F main.py

🖼️ GUI 程式打包(無命令列視窗)

bash
pyinstaller -F -w main.py
  • 產出在 dist/main.exe

  • 若有資源檔案、圖示可用:

    bash
    pyinstaller -F -w --icon=myicon.ico main.py

📁 補充:.pyc 編譯後的位置與命名

若你有這個檔案:

my_project/ └── utils.py

編譯後會產生這個:

markdown
my_project/ └── __pycache__/ └── utils.cpython-311.pyc ← Python 3.11 的編譯版本

📝 小提醒

  • .pyc 只是提高模組載入速度,不會加速運算執行效能

  • 若你要保護原始碼但又不想打包 .exe,只釋出 .pyc 是個折衷方案。

  • GUI 用 .pyw 啟動 .pyc 可以避免跳出 DOS 視窗。

Python 程式檔案副檔名全解 (更新版 V2.0)

 Python 雖是直譯語言,但在執行前會先將 .py 原始碼編譯為位元組碼(Bytecode),產生 .pyc.pyo 檔案,再由 Python 虛擬機器執行。


🔤 一、常見副檔名與用途

副檔名功能說明
.pyPython 原始碼,開發與執行的主要程式檔案。
.pyw.py 相同,但在 Windows 中以 pythonw.exe 執行,不顯示命令列視窗,常用於 GUI 程式。
.pyc編譯後的位元組碼,用於加快模組載入速度,自動由 import 時產生。
.pyo編譯後的「優化版」位元組碼(Python 3.5 前可用,現已合併至 .pyc)。
.pydWindows 平台下的動態連結庫(DLL),用 C/C++ 編寫的擴充模組,Python 可 import

⚙️ 二、位元組碼編譯與使用

✅ 1. 單一檔案手動編譯 .py → .pyc

python
import py_compile py_compile.compile(r'H:\game\test.py')
  • file: 原始碼路徑

  • cfile: 輸出檔名(可選)

  • dfile: 錯誤資訊輸出位置(可選)

  • doraise: 為 True 時會主動丟出 PyCompileError


✅ 2. 批次編譯整個資料夾

python
import compileall compileall.compile_dir(r'H:\game')

✅ 3. 編譯優化位元組碼 .pyo(Python 3.5 以前)

bash
python -O -m py_compile file.py
  • -O:開啟最佳化模式,會省略 assert、debug 等語句。

  • 輸出為 .pyo,但在 Python 3.5+ 之後已合併進 .pyc


🧱 三、程式釋出方式建議

✅ 1. 打包為 EXE 檔(推薦 GUI)

使用 pyinstaller

bash
pyinstaller -F example.py # 打包為單一檔 pyinstaller -w -F example.py # GUI 版不顯示控制台
  • 生成 .exe,使用者無需安裝 Python 環境。


✅ 2. 發布 .pyc / .pyo

適合希望保護原始碼,但使用者已有 Python 環境的情境:

  • 編譯成 .pyc 再部署

  • GUI 程式可使用 .pyw 呼叫主 .pyc


✅ 3. 直接發布 .py 原始碼

適合開源、教育、內部測試等情境,簡單直接,無需額外步驟。


🧠 四、補充資訊

  • .pyc 會自動生成於 __pycache__ 資料夾中,檔名格式為:module.cpython-XY.pyc

  • Python 3.5 起 .pyo.pyc 已合併為單一優化 .pyc

  • .pyd 像是 Windows 的 .dll,常由 C/C++ 使用 Cython 或 CPython API 開發


📝 心得與總結

Python 雖屬直譯型語言,但實際運作中也具備「編譯階段」的概念,這使得 .pyc / .pyo 等位元組碼形式能提升效能並兼顧保護原始碼。針對不同的釋出場景,可以靈活選擇:

  • 開源:釋出 .py

  • 商用封裝:轉 .pyc 或使用 pyinstaller 打包

  • GUI 程式:使用 .pyw 搭配打包工具

對於有授權、隱私、發佈需求的 Python 專案,善用副檔名與打包技巧可以讓開發流程更專業且安全。

2024年12月10日 星期二

YOLO 目前發展的時間軸

 


YOLOv1: 最早的版本,奠定了YOLO系列的基礎。
YOLOv2: 引入批次正規化、錨框和尺寸聚類等技術,提升了模型的性能。
YOLOv3: 採用更有效的骨幹網路、多尺度特徵融合等方法,進一步增強了模型的表現。
YOLOv4: 引入Mosaic資料增強、無錨框偵測頭、新的損失函數等創新,大幅提升了模型的準確度。
YOLOv5: 優化了超參數,整合實驗追蹤和自動匯出功能,使其更易於使用。
YOLOv6: 由美團開放原始碼,並應用於其許多自動配送機器人中。
YOLOv7: 新增了人體姿態估計等任務。
YOLOv8: 由Ultralytics推出,支援更廣泛的視覺AI任務,性能更佳。
YOLOv9: 引入可程式化梯度資訊(PGI)和通用高效層聚合網路(GELAN)等創新方法。
YOLOv10: 由清華大學研究人員開發,採用端到端偵測頭,無需非極大值抑制(NMS)。
YOLOv11: Ultralytics最新的版本,在多種任務上取得了最先進的性能
Ps: 
    >> V4,V7,V9 於技術上有改進突破 提高準確率和速度 台灣中研院發表 
    >> V5, V8,V11 為 Ultralytics推出改進版本 無核心技術貢獻 但改進使用介面使YOLO容易使用 
         可以用 Pytorch 工具編譯 集多個類模型可適合各種平台使用








Yolov8 發展資源 模型分類

 



#YOLOv8 的不同版本與特色

#參數說明:
模型大小 (MB): 模型檔的大小,直接影響模型的部署和存儲。
參數量 (M): 模型中的可訓練參數數量,影響模型的複雜度和訓練時間。
FLOPs (G): 浮點運算次數,反映模型的計算量,影響推理速度。
輸入尺寸: 模型輸入圖像的尺寸,影響模型的感受野和檢測精度。
mAP@0.5: 平均精度均值,用於評估模型的整體性能。
mAP@0.5:0.95: 平均精度均值,考慮了不同 IoU 閾值下的性能,更全面地反映模型的性能。
推理速度 (FPS): 模型在特定硬體上的推理速度,單位元為幀每秒。
適用場景: 根據模型的性能特點,建議的應用場景。

#模型特性:
YOLOv8n: 極輕量,適合資源受限設備,如嵌入式系統和移動設備。
YOLOv8s: 速度與精度平衡,適用於一般目標檢測任務。
YOLOv8m: 精度較高,速度適中,適合中等複雜度場景。
YOLOv8l: 適合複雜場景,精度高,但對計算資源要求較高。
YOLOv8x: 最大模型,精度最高,但對計算資源要求極高。









2024年12月2日 星期一

Python 載入 gcc DLL (so) Note

 

動態載入C library (DLL)

從第一次知道python這個語言時,就聽聞python的其中一項強大之處,高彈性:
直接利用python coding方便又快速,真的遇到關鍵的效能瓶頸,再以C語言改寫即可。
CPython能達到這項目的的方法,個人知道有2種:Python/C API和ctypes.

P.S. 當然,如果目的是加速或與其他語言做binding就不只這兩項了。
例如RPython, Cython, …等派生或是擴充語言,但那進來考慮實在有點消化不完。

一來目前主要是想摸熟python本身的特性,
二來由於目前個人感興趣的部分在於CPython和C如何直接溝通,因此其他方式暫時不考慮了。

ctypes

最後稍微比較過後,Python及C之間的API也決定暫時擱置。
以之前經驗來說,這類的API接口大多只要搞懂制式的規格和作用,
剩下來的就是類似將內容填入表格的繁瑣工作。
相較之下,若能在幾乎不動C source code的情形下做到這件事情,個人認為有很大的優勢。

以下是一個用C語言寫成簡單(幾乎無經過修飾)的開方根的程式:

/* File: c_sqrt.c */
doublesqrt(doublek) {
   int i;
   double x=k;
   for(i=0; i<5; i++)
      x = x - (x*x-k)/(2*x); // Newton's Iteration.
   return x;  
}

接著把這個compile成shared library.

$ gcc c_sqrt.c -shared -fPIC -O2 -oc_sqrt.so

需要注意的是,由於個人的電腦都是Linux/OS X等類Unix系的,所以動態函式庫是.so檔。
而在python中,則直接利用ctypes module來讀檔:

import  ctypes
dyn = ctype.CDLL('./c_sqrt.so')  
dyn.sqrt.argtypes = [ctypes.c_double] # default: None
dyn.sqrt.restype  =  ctypes.c_double  # default: None  
                                      # default: c_int
print( dyn.sqrt(5) )

這段程式造出一個CDLL的物件dyn。
利用dyn去讀取sqrt時,會到c_sqrt.so找到sqrt的symbol,然後加到dyn這個物件裡。

然而預設的情況下,一個由CDLL讀入的C函數是無參數、回傳值為整數的函數。
如果直接呼叫dyn.sqrt(5)也只會得到0而已。
必須修改傳入的參數的型別(如第四行那樣,有多少參數就寫進list裡),
restype則是回傳的型別。

若回傳的值是一個結構包裝的東西,
或許還得要再經過宣告一個新的類別來使用:

from ctypes import *
class foo(Structure):
   _fields_=[("val", c_int),  ("dat", POINTER(c_int))]

參考資料:

  1. Python Document: ctypes — A foreign function library for Python
  2. 程式設計遇上小提琴 - Python的進步: ctypes
  3. (參考) Dynamically Loaded (DL) Libraries ,看看C語言中怎麼做到上面的事情.

參考自  ==> 
https://www.gitbook.com/?utm_source=legacy&utm_medium=redirect&utm_campaign=close_legacy