當前位置:首頁 » 編程語言 » c語言調用python腳本
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

c語言調用python腳本

發布時間: 2022-04-22 07:20:53

Ⅰ 求助 關於c程序中嵌入Python的問題

在C/C++中嵌入Python也比較簡單,首先需要在VC中添加Python的include文件目錄和lib文件目錄:
VC6.0下,打開 tools->options->directories->show directories for,將Python安裝目錄下的inlude目錄添加到inlude files項中,將libs目錄添加到library files項中。
VC2005下,打開tools->options->項目和解決方案->VC++目錄,然後做相同工作。

代碼如下:
//在debug下執行出錯,「無法找到python31_d.lib文件」,後查到原因是:在debug下生成必須要有python31_d.lib文件,否則只能在release下生成
#include <python.h>
int main()
{
Py_Initialize();
PyRun_SimpleString("Print 'hi, python!'");
Py_Finalize();
return 0;
}

Py_Initialize函數原型是:void Py_Initialize(),在嵌入Python腳本時必須使用該函數,它初始化Python解釋器,在使用其他的Python/C API之前必須先調用該函數。可以使用Py_IsInitialized函數判斷是否初始化成功,成功返回True。
PyRun_SimpleString函數原型是int PyRun_SimpleString(const char *command),用來執行一段Python代碼。注意:是否需要維持語句間的縮進呢?
Py_Finalize函數原型是void Py_Finalize(),用於關閉Python解釋器,釋放解釋器所佔用的資源。

PyRun_SimpleFile函數可以用來運行".py"腳本文件,函數原型如下:
int PyRun_SimpleFile(FILE *fp, const char *filename);
其 中fp是打開的文件指針,filename是要運行的python腳本文件名。但是由於該函數官方發布的是由visual studio 2003.NET編譯的,如果使用其他版本的編譯器,FILE定義可能由於版本原因導致崩潰。同時,為簡便起見可以使用如下方式來代替該函數:
PyRun_SimpleString("execfile(『file.py』)"); //使用execfile來運行python文件

Py_BuildValue()用於對數字和字元串進行轉換處理,變成Python中相應的數據類型(在c語言中,所有Python類型都被聲明為PyObject類型),函數原型如下:
PyObject *Py_BuildValue(const char *format, …..);
PyString_String()用於將PyObject*類型的變數轉換成C語言可以處理的char*型,具體原型如下:
char* PyString_String(PyObject *p);

列表操作函數:
PyObject * PyList_New(Py_ssize_t len);
int PyList_SetItem(PyObject *list, Py_ssize_t index, PyObject *item);
PyObject * PyList_GetItem(PyObject *list, Py_ssize_t index);
int PyList_Append(PyObject *list, PyObject *item);
int PyList_Sort(PyObject *list);
int PyList_Reverse(PyObject *list);
Py_ssize_t PyList_Size(PyObject *list);

元組操作函數:
int PyTuple_New(Py_ssize_t len);
int PyTuple_SetItem(PyObject *p, Py_ssize_t pos, PyObject *o);
PyObject * PyTuple_GetItem(PyObject *p, Py_ssize_t pos);
int _PyTuple_Resize(PyObject **p, Py_ssize_t newsize); //注意是**指針

字典操作函數:
PyObject * PyDict_New();
int PyDict_SetItem(PyObject *p, PyObject *key, PyObject *val);
int PyDict_SetItemString(PyObject *p, const char *key, PyObject *val);
PyObject* PyDict_GetItem(PyObject *p, PyObject *key);
PyObject* PyDict_GetItemString(PyObject *p, const char *key);
//與PyDict_SetItemString對應
int PyDict_DelItem(PyObject *p, PyObject *key);
int PyDict_DelItemString(PyObject *p, char *key);
//與PyDict_SetItemString對應
int PyDict_Next(PyObject *p, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue);
PyObject* PyDict_Items(PyObject *p);
PyObject* PyDict_keys(PyObject *p);
PyObject* PyDict_Values(PyObject *p);

在C/C++中使用Python對象應正確地處理引用計數問題,否則容易導致內存泄漏。當使用Python/C API中的函數創建列表、元組、字典等後,在對其完成操作後應該使用Py_CLEAR()和Py_DECREF()等宏來銷毀這些對象。原型如下:
void Py_CLEAR(PyObject *o);
void Py_DECREF(PyObject *o);
其中,對於Py_CLEAR函數,參數可以為NULL指針,表示不進行任何操作,但是Py_DECREF函數不能為NULL指針,否則導致錯誤。

使用PyImport_Import()函數可以在C中導入Python模塊,返回一個模塊對象。函數原型為:
PyObject* PyImport_Import(PyObject *name);
PyMole_GetDict()函數可以獲得Python模塊中的函數列表,返回一個字典,字典中的關鍵字為函數名,值為函數的調用地址。原型如下:
PyObject* PyMole_GetDict(PyObject *mole);
使用PyObject_CallObject()函數和PyObject_CallFunction()函數可以在C中調用Python中的函數,原型如下:
PyObject* PyObject_CallObject(PyObject *callable_object, PyObject *args);
//args是元組形式
PyObject* PyObject_CallFunction(PyObject *callable, char *format, ……);
//format是類似」iss」這樣的參數類型,後面是指定參數
可以使用PyCallable_Check(func)來判斷是否可以調用函數,可以則返回True。

Ⅱ c可以調用python嗎

可以的。

C中內嵌Python
新建立一個工程,首先需要將工作目錄設置到Python-3.1.1PCbuild中,以獲取到動態庫,至於靜態庫的包含,Include目錄的指定,那自然也是少不了的。文件中需要包含Python.h文件,這也是必須的。
介面中
Py_Initialize();
Py_Finalize();

其他的根據需求,再引入相應的python builder 即可

Ⅲ 如何編譯c文件中調用 cython

以下總結出幾種在Python 中調用 C/C++ 代碼的方法
--------------------------------------------------------------------
發現做便捷的是使用popen
from os import popen
popen('/home/pengyan/Downloads/VIC/sanxia/vicNl -g /home/pengyan/Downloads/VIC/sanxia/xings_global')
popen('/home/pengyan/Downloads/VIC/sanxia/rout /home/pengyan/Downloads/VIC/sanxia/xings_rout')
?? 目前還不會用python 切換文件目錄
可以採用絕對路徑,但是好像絕對路徑時,計算速度變慢
-------------------------------------------------------------------
使用ctypes 模塊調用 C 動態庫
從Python2.5 開始, Python 開始提供 ctypes 模塊來提供對 C 語言編譯的動態庫文件的調用。注意, 這里特指C 的動態庫 ,用C++ 編譯的動態庫 ctypes 雖然能夠載入,但調用時的函數名已經由於 C++ 的重載特性被加以修改,難以調用。 使用 ctypes 調用 C 動態庫的好處在於不用進行額外的開發,可以直接使用編譯好的動態庫。 ctypes 提供了完整的 C 類型封裝,也支持自定義類型,大大減少在調用過程中的工作量。 ctypes 的使用很簡單,只需熟悉 python 封裝與 C 中的對應關系即可。以下用一個簡單的例子來說明:
from ctypes import * #導入ctypes模塊
libc = cdll.LoadLibrary("libc.so.6") #載入libc動態庫
str = c_char_p(' Hello World! ') #使用char *在ctypes中的對應封裝c_char_p,相當於char* str=」Hello World!」
libc.printf(「yell: %s\n」, str ) #調用printf函數
ctypes的功能當然遠不止這些,有興趣的同學可以參考這里 http://docs.python.org/library/ctypes.html
使用Python 的擴展( Extending )機制
ctypes很方便地可以調用 C 的動態庫,但是對 C++ 編譯的動態庫,調用起來很困難。這種情況利用 Python 的 Extending 機制就可以解決。 Python 提供了一套完整的框架來使用 C/C++ 編寫擴展庫,可以很靈活的開發 C++ 擴展模塊。這種方法的缺點是工作量比較大,需要為每一個方法編寫介面,這里不做詳細介紹,可以參考: http://docs.python.org/extending/extending.html#writing-extensions-in-c
那麼有什麼辦法可以高效的調用C++ 動態庫呢,答案是 SWIG 。
使用SWIG 生成擴展模塊
上面提到了Python 的擴展機制,缺點是工作量比較大,這里介紹一個工具 SWIG 。 SWIG 是一種簡化腳本語言與 C/C++ 介面的開發工具,通過包裝和編譯 C 語言程序來達到與腳本語言通訊目的的工具。它正是基於 Python 的擴展機制,自動生成介面文件,再編譯成可以被 Python 調用的動態庫擴展模塊。
使用SWIG 生成擴展模塊分為以下幾步:
將需要調用的代碼編譯成目標文件(.o) ;
用SWIG 讀取編寫描述文件 (.i) ,生成介面文件 (.cxx) ;
將介面文件編譯為目標文件(.o) ;
將介面文件的目標文件和原代碼段的目標文件一起編譯成動態庫 ;
假設有如下文件
swig_ex.cpp 需要轉換成擴展庫的原始代碼,包含一個int fact(int) 函數
swig_ex.h 原始代碼的頭文件
swig_ex.i SWIG描述文件
swig_ex.i是一個描述文件,有 SWIG 自己的語法,比較簡單,內容如下:

%mole swig_ex
%{
#define SWIG_FILE_WITH_INIT
#include "swig_ex.h"
%}
int fact(int n);
再寫一個Makefile 來把這些文件編譯成動態庫 :

all: swig_ex.o swig_ex_wrap.o _swig_ex.so
swig_ex.o: swig_ex.cpp swig_ex.h #編譯源文件
g++ -fPIC -c swig_ex.cpp
swig_ex_wrap.o: swig_ex.i swig_ex.o #根據 SWIG 描述文件 (.i) 生成介面文件 (.cxx) ,再編譯之
swig -c++ -python swig_ex.i
g++ -O2 -fPIC -c swig_ex_wrap.cxx -I/home/work/linyi/autoframe/tool/python/include/python2.6/
_swig_ex.so: swig_ex_wrap.o #將目標文件打包成動態庫
g++ -shared swig_ex.o swig_ex_wrap.o -o _swig_ex.so
.PHONY: clean
clean:
rm -rf swig_ex_wrap.* swig_ex.py _swig_ex.so
編譯好以後會有一個so 和 py 文件,寫一個 setup.py 把他們安裝到 python 目錄就可以和其他模塊一樣被 python 調用了:

Import swig_ex
swig_ex.fact(10)
參考文檔地址:http://www.swig.org/Doc1.3/SWIGDocumentation.html
原始但有效的方法
除了上面這些方法,在Python 中借用 C/C++ 代碼最原始有效的方法就是將代碼編譯成可執行程序,從 Python 里用 Popen 方法來調用獲取輸出。這種方法簡單有效,缺點是不夠靈活,有比較大的局限性,不過在很多情況下也已經足夠了。

pipe = os.popen('./tool –a %s –b %s' % (「hello」, 「world」))
re = pipe.read()
其他方法
以上這些方法基本上已經能滿足Python 調用 C/C++ 的需求了,此外還有一些方法,例如使用 Boost.Python ,使用 Pyrex ,這些方法都能提供 Python 與 C/C++ 的交互。
總結
在Python 中引用 C/C++ 模塊的方法較多,根據需要從中選擇恰當的方法可以減少很多工作量。
在Python 中引用 C/C++ 模塊彌補了 Python 腳本測試框架的很多不足,在提高代碼復用率的同時,模塊的性能也大大提高。

Ⅳ 怎樣讓Python腳本與C++程序互相調用

二、Python調用C/C++

1、Python調用C動態鏈接庫

Python調用C庫比較簡單,不經過任何封裝打包成so,再使用python的ctypes調用即可。
(1)C語言文件:pycall.c

[html] view plain
/***gcc -o libpycall.so -shared -fPIC pycall.c*/
#include <stdio.h>
#include <stdlib.h>
int foo(int a, int b)
{
printf("you input %d and %d\n", a, b);
return a+b;
}
(2)gcc編譯生成動態庫libpycall.so:gcc -o libpycall.so -shared -fPIC pycall.c。使用g++編譯生成C動態庫的代碼中的函數或者方法時,需要使用extern "C"來進行編譯。
(3)Python調用動態庫的文件:pycall.py

[html] view plain
import ctypes
ll = ctypes.cdll.LoadLibrary
lib = ll("./libpycall.so")
lib.foo(1, 3)
print '***finish***'
(4)運行結果:

2、Python調用C++(類)動態鏈接庫

需要extern "C"來輔助,也就是說還是只能調用C函數,不能直接調用方法,但是能解析C++方法。不是用extern "C",構建後的動態鏈接庫沒有這些函數的符號表。
(1)C++類文件:pycallclass.cpp

[html] view plain
#include <iostream>
using namespace std;

class TestLib
{
public:
void display();
void display(int a);
};
void TestLib::display() {
cout<<"First display"<<endl;
}

void TestLib::display(int a) {
cout<<"Second display:"<<a<<endl;
}
extern "C" {
TestLib obj;
void display() {
obj.display();
}
void display_int() {
obj.display(2);
}
}
(2)g++編譯生成動態庫libpycall.so:g++ -o libpycallclass.so -shared -fPIC pycallclass.cpp。
(3)Python調用動態庫的文件:pycallclass.py

[html] view plain
import ctypes
so = ctypes.cdll.LoadLibrary
lib = so("./libpycallclass.so")
print 'display()'
lib.display()
print 'display(100)'
lib.display_int(100)
(4)運行結果:

3、Python調用C/C++可執行程序
(1)C/C++程序:main.cpp

[html] view plain
#include <iostream>
using namespace std;
int test()
{
int a = 10, b = 5;
return a+b;
}
int main()
{
cout<<"---begin---"<<endl;
int num = test();
cout<<"num="<<num<<endl;
cout<<"---end---"<<endl;
}
(2)編譯成二進制可執行文件:g++ -o testmain main.cpp。
(3)Python調用程序:main.py

[html] view plain
import commands
import os
main = "./testmain"
if os.path.exists(main):
rc, out = commands.getstatusoutput(main)
print 'rc = %d, \nout = %s' % (rc, out)

print '*'*10
f = os.popen(main)
data = f.readlines()
f.close()
print data

print '*'*10
os.system(main)
(4)運行結果:

4、擴展Python(C++為Python編寫擴展模塊)
所有能被整合或導入到其它python腳本的代碼,都可以被稱為擴展。可以用Python來寫擴展,也可以用C和C++之類的編譯型的語言來寫擴展。Python在設計之初就考慮到要讓模塊的導入機制足夠抽象。抽象到讓使用模塊的代碼無法了解到模塊的具體實現細節。Python的可擴展性具有的優點:方便為語言增加新功能、具有可定製性、代碼可以實現復用等。
為 Python 創建擴展需要三個主要的步驟:創建應用程序代碼、利用樣板來包裝代碼和編譯與測試。
(1)創建應用程序代碼

[html] view plain
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int fac(int n)
{
if (n < 2) return(1); /* 0! == 1! == 1 */
return (n)*fac(n-1); /* n! == n*(n-1)! */
}

char *reverse(char *s)
{
register char t, /* tmp */
*p = s, /* fwd */
*q = (s + (strlen(s) - 1)); /* bwd */

while (p < q) /* if p < q */
{
t = *p; /* swap & move ptrs */
*p++ = *q;
*q-- = t;
}
return(s);
}

int main()
{
char s[BUFSIZ];
printf("4! == %d\n", fac(4));
printf("8! == %d\n", fac(8));
printf("12! == %d\n", fac(12));
strcpy(s, "abcdef");
printf("reversing 'abcdef', we get '%s'\n", \
reverse(s));
strcpy(s, "madam");
printf("reversing 'madam', we get '%s'\n", \
reverse(s));
return 0;
}
上述代碼中有兩個函數,一個是遞歸求階乘的函數fac();另一個reverse()函數實現了一個簡單的字元串反轉演算法,其主要目的是修改傳入的字元串,使其內容完全反轉,但不需要申請內存後反著復制的方法。
(2)用樣板來包裝代碼
介面的代碼被稱為「樣板」代碼,它是應用程序代碼與Python解釋器之間進行交互所必不可少的一部分。樣板主要分為4步:a、包含Python的頭文件;b、為每個模塊的每一個函數增加一個型如PyObject* Mole_func()的包裝函數;c、為每個模塊增加一個型如PyMethodDef MoleMethods[]的數組;d、增加模塊初始化函數void initMole()。

Ⅳ C中調用Python函數,找不到模塊

是因為你的模塊的路徑不對,必須先指定路徑
PyObject *sys = PyImport_ImportMole("sys");
PyObject *path = PyObject_GetAttrString(sys, "path");
PyList_Append(path, PyString_FromString("."));

Ⅵ linux C語言調用Python腳本

比如什麼變數呢?
可以用命令行參數啊
system("python xxx.py arg1 arg2 ...")
如果讓python接收參數自己查一下

Ⅶ 怎麼用cmd 運行python

用cmd運行python程序

步驟:(1)打開cmd。

(2)轉到你要運行的文件所在的盤(例如:E盤)。輸入: e: 回車zhuan

(3)打開你要運行的文件所在的文件夾(例如:E:\ABC\123)。輸入:cd E:\ABC\123 回車

(4)運行程shu序。 輸入:python ***.py(程序文件的名字) 回車

(7)c語言調用python腳本擴展閱讀

在windows cmd下運行python,需要配置python環境變數,現在假設python安裝在D:\Python目錄下,設置環境變數方法如下: 方法一、我的電腦->屬性->高級->環境變數->系統變數 ,在系統變數里找到PATH,點擊「編輯」,在結尾加上 ";D:\Python"(不要引號)

Ⅷ C調用Python一個運行時間長的函數,如何實時

如果要在test.py中調用腳本func.py腳本

首先,兩個腳本文件要放在pythonpath下,其次在test.py腳本的開頭寫上import func,這樣就可以直接調用func中的函數方法了。

Ⅸ c語言調用python有哪些好處

python是腳本語言,簡潔,易用,可以幫助你寫一些很方便的小程序,庫也豐富,不需要c那麼大規模復雜,所以,有些東西交給腳本語言做,速度快,花費時間少