匯出 C 函式模組給 Python3 呼叫

2021-07-16 08:59:15 字數 2577 閱讀 6520

記錄一下為了讓自己用 qt 和 c++ 寫的**工具能夠被組裡其他用 python 工作的同學們使用,特地搜了下如何將自己的函式封裝並作為 python3 的 module 匯出的方法,整理出來記錄一下。

由於 python 的基本功能模組本身既是由 c/c++ 開發出來的,在 python 中想使用 c/c++ 開發的動態庫也不是什麼難事。這裡只是簡單記錄一下我在 python3 環境中開發乙個「hello world」級別模組的基本步驟。

在 python 中使用 c/c++ 函式的常見方法有兩種:

1.使用 ctypes 下的 cdll 函式匯入自己的動態鏈結庫匯出函式,典型用法如下:鏈結

from ctypes import *;

h=cdll('msvcrt.dll')

h.printf('a=%d,b=%d,a+b=%d',1,2,1+2);

import ***

a = ***.func()

***.func2(a)

debian 8.5 + python 3.4.2 + qtcreator

注意:編譯需要的標頭檔案和靜態庫檔案需要預先安裝好,否則報 undefined reference 錯誤。安裝指令:

sudo apt-get install python3-dev g++-4.9
c++ 部分:

#include 

/* python.h 必須作為第乙個標頭檔案被引用,因為其中包含對其他庫函式的重定義 */

#include

/* 為了方便我的函式定義在這裡,其實可以定義在外邊,引用標頭檔案 */

unsigned

int ***_u_ff(float a, float b)

void ***_show_f(float f)

/* 現在開始是匯出函式到 python3 需要的東西 */

static pyobject *py_fadd2uint(pyobject *self, pyobject *args)

ret = ***_u_ff(a, b);

return py_buildvalue("i", ret);

}static pyobject *py_showfloat(pyobject *self, pyobject *args)

***_show_f(a);

return py_none;

}static pymethoddef ***_methods = ,

,/* 固定的結尾標誌,用來判斷結構陣列的結尾 */

};static

struct pymoduledef ***_module = ;

pymodinit_func pyinit_***(void)

printf("module initialized\r\n");

return m;

}

使用 gcc 編譯的情況下,編譯指令為:

$gcc -fpic -c -i /usr/include/python3.4 -i /usr/lib/python3.4/config-x86_64-linux-gnu -lpython3.4m main.cpp

$gcc -shared -o ***.so main.o

使用 qt creator 編譯,則在 .pro 檔案裡加入

template = lib                # 使用動態鏈結庫模板

version = 0.0

.1 # 要發布的庫版本號

target = *** # 要發布的庫名字

sources += main.cpp

includepath += /usr/include/python3.4 \

libs += -lpython3.4m

編譯好會得到 lib***.so,lib***.so.0 等等一大堆,此時由於 python 尋找模組的時候只會搜尋同名的庫檔案,需要刪除檔名前面的 lib,保證最後可以使用的庫檔名應該是 ***.so

最後,在庫當前目錄開啟console,從 python3 呼叫寫好的模組就好了:

>> import ***

module initialized

>> a = ***.fadd2uint(1.0, 1.0)

>> print(type

(a))

>> print(a)

1073741824

>> ***.showfloat(1.3)

1.300000

z由於 python 對沒有用的變數使用自動**機制,因此從 c/c++ 中不能直接傳出資料指標給 python (非要傳遞的話,用資料型別」o」可以,但是傳出的指標無法析構,且會導致 python 執行中發生各種錯誤。除非 ***.useref(***.makeref()) 這種形式的呼叫,不然不要隨意暴露指標給 python)。對指標傳遞的時候需要額外做些操作說明,這次沒有整理,留到下次寫。

Python3 隨機數模組 random

import random 用於生成乙個0到1的隨機浮點數 0 n 1.0 num1 random.random 用於生成乙個指定範圍內的隨機浮點數,兩個引數其中乙個是上限,乙個是下限。如果 a b,則生成的隨機數 n b n a。如果 a b,則 a n b。num2 random.uniform...

python函式 模組

一 函式 函式是組織好的,可以重複利用,用來實現一定功能的 段。1 函式的組成部分 1 函式 塊以 def 關鍵字開始,後接函式名稱和括號 然後是冒號 2 任何傳入的引數和自變數必須放在 中 3 函式第一行語句可以寫注釋表明函式的功能 4 段,描述了函式實現的功能,需要縮排 5 return 表示式...

Python函式 模組

模組 定義函式使用def 函式體寫在縮排塊中,函式的返回值用return語句返回,函式執行完畢也沒有return語句時,自動return none 如果想定義乙個什麼事也不做的空函式,可以用pass語句,pass可以用來作為佔位符,如果沒想好怎麼寫,可以先寫乙個pass函式,讓 執行起來 函式 含義...