windows下c語言程式呼叫python實踐

2021-08-09 19:01:44 字數 3720 閱讀 9261

目的

執行環境

注意點:

在實際的工作中,為了方便利用python寫的程式(因為python中有很多功能強大的函式庫),有時需要進行c、c++與python的混合程式設計,特別是需要在c程式中呼叫python指令碼。關於c程式呼叫python**,除了官方文件,網上有很多好的文章可以參考,下面開展實踐,實驗的主要目的是利用c程式呼叫python函式畫一幅圖。

#include int

main(int argc, char *argv)

py_setprogramname(program); /* optional but recommended */

py_initialize();

pyrun_******string("from time import time,ctime\n"

"print('today is', ctime(time()))\n");

if (py_finalizeex() < 0)

pymem_rawfree(program);

return 0;

}

執行這個程式,可以利用python的time庫獲得當前日期,這個程式看起來內容很多,但其實呼叫python指令碼的關鍵語句只有3句,其他更多的是異常處理和記憶體管理。因此,這個程式可以簡化為:

#include int main(int argc, char* argv)

該程式eg1b.c的編譯執行結果為:

d:\cpython>gcc -o eg1b.exe eg1b.c -wall -lpython36 -lc:\anaconda3\libs -ic:\anaconda3\include

d:\cpython>eg1b

today is tue oct 24 23:22:45 2017

d:\cpython>

注意到在執行的時候,如果不設定path環境變數,執行會出現錯誤,提示為缺少python36.dll,解決的方法是加入環境變數:

set path="c:\anaconda3;%path%"
如果不設定pythonpath環境變數,執行會出現錯誤,提示為:

fatal python error: py_initialize: unable to load the file system codec

modulenotfounderror: no module named 'encodings'

current thread 0x000011d8 (most recent call first):

解決方法是加入pythonpath環境變數,參考py_initialize fails - unable to load the file system codec,比如:

set pythonpath="c:\anaconda3;c:\anaconda3\libs;c:\anaconda3\dlls;c:\anaconda3\lib;c:\anaconda3\library\bin;"
當然另乙個解決方法是,將eg1b.exe檔案複製到c:\anaconda3目錄下去執行,這樣就不需要設定環境變數。

上述這種方法在官方文件中稱為高層的嵌入,即:使用高層的介面來執行python的任意**片段。但這種方法不存在資料的互動,如果需要資料互動,那麼就需要採用下面一種方法:

將資料值從c的型別轉換到python型別,

執行函式使用轉換後的資料呼叫python介面過程,

將呼叫返回的資料從python型別轉換為c型別的資料

我們仍然看官方文件提供的例子,這裡直接做了簡化,**eg4.c為:

#include #include int test()

int main(int argc, char* argv)

python指令碼testsci.py為:

import numpy as np

import pylab as pl

def plotmap(var):

x = np.linspace(0, var*np.pi, 100)

pl.plot(x, np.sin(x))

pl.show()

return 0

def multiply(a,b):

print("will compute", a, "times", b)

c = 0

for i in range(0, a):

c = c + b

return c

if __name__=="__main__":

plotmap(1)

multiply(2,3)

該程式eg4.c的編譯執行結果為:

d:\cpython>gcc -o eg4.exe eg4.c -wall -lpython36 -lc:\anaconda3\libs -ic:\anaconda3\include

eg4.c: in function 'test':

eg4.c:8:30: warning: unused variable 'pdict' [-wunused-variable]

pyobject *pname, *pmodule, *pdict, *pfunc;

^~~~~

d:\cpython>set pythonpath="c:\anaconda3;c:\anaconda3\libs;c:\anaconda3\dlls;c:\anaconda3\lib;c:\anaconda3\library\bin;"

d:\cpython>eg4

will compute 3 times 4

result of call: 12

d:\cpython>

其中畫出的圖為:

注意,這裡繪圖需要特殊的qt庫來支援,如果沒有處理的畫,圖不會繪製出,並會提示錯誤:

這個問題的解決是,通過拷貝c:\anaconda3\library\plugins\platforms這個資料夾到當前執行檔案所在目錄來實現的。具體參考:網頁

通過上述實踐,完成了c程式呼叫python程式的工作,在進一步的應用中可以採用類似的方法呼叫python寫的更多指令碼,以得到更便捷的功能實現。

[1]. python362.chm,extending and embedding the python interpreter

[2]. 如何實現 c/c++ 與 python 的通訊?

[3]. 使用c語言呼叫python小結

[4]. py_initialize fails - unable to load the file system codec

[5].

參考資料3中給出了對類的方法的呼叫,同時也展示了資料型別轉換的不同方法,區別於官方例子中使用元組資料,而使用py_buildvalue和pyarg_parse。當然這些資訊,參考官方文件中的內容也可以看到。

v1.0 20171025 完成基本內容

C語言程式呼叫SQLite

寫個c語言程式呼叫sqlite 現在我們來寫個c c 程式,呼叫 sqlite 的 api 介面函式。下面是乙個c程式的例子,顯示怎麼使用 sqlite 的 c c 介面.資料庫的名字由第乙個引數取得且第二個引數或更多的引數是 sql 執行語句.這個函式呼叫sqlite3 open 在 22 行開啟...

windows下c 程式與python程式間通訊

c 收 server 命名管道採用基於連線的可靠傳輸方式,只能一對一傳輸 include include define buf size 1024 using std cerr using std cout using std endl int main else 等待命名管道客戶端連線 if co...

windows下C 如何呼叫matlab程式

實驗平台 matlab r2016b vs2013 思路 1.設定matlab的編譯器,使用外部的vc或者gcc等編譯器。2.編譯m檔案成dll 3.設定vs的include路徑和lib鏈結庫的路徑 4.編寫c 呼叫dll 步驟 1.設定matlab的編譯器 在命令列視窗下,輸入並執行如下命令 me...