當前位置:首頁 » 編程語言 » python調用c指針

python調用c指針

發布時間: 2022-06-14 05:39:31

python 調用C代碼獲取數據,C代碼要求1個結構參數, 其中有項目是指向緩沖區的指針,如何實現參數賦值

class stdata(Structure):
_fields_ = [('pBuf', c_char_p), ('buflen', c_int)]

N=100
buf = create_string_buffer(N)
d = stdata()
d.buflen = N
d.pBuf = cast(buf, c_char_p)

n = CallMyCFunc_GetData(byref(d))

關鍵在於create_string_buffer創建可寫buffer;cast轉換為char*類型。

② python怎麼調用c的動態鏈接庫

Python調用C/C++動態鏈接庫的需求
在自動化測試過程中,難免會遇到語言混合使用的情況,這不,我們也遇到了。初步決定採用Robot Framework作為自動化測試框架後,其支持Java和Python,而Python作為主流的語言,怎麼能放棄使用它的機會^_^。 然而產品採用是古老90年代開發的C/S結構,因為古老,當時也沒有考慮到對產品的測試進行自動化,Client端並沒有預留CLI(Command Line interface)形式的介面,真是雪上加霜啊。
那怎麼自動化?採用AutoIT來對客戶端界面進行自動化測試?可惜AutoIT對當初開發採用的控制項識別不是很好,如果採用控制項所在位置來進行控制的方式,又會導致自動化測試並不是很穩定。那麼!!!只有自己開發介面了,目前在Client端開發出CLI形式的介面,將其封裝為DLL,然後在Robot FrameWork框架中採用Python對DLL進行調用。任務艱巨哪!
Python調用DLL例子
示例一
首先,在創建一個DLL工程(本人是在VS 2005中創建),頭文件:
[cpp] view plain 在CODE上查看代碼片派生到我的代碼片//hello.h
#ifdef EXPORT_HELLO_DLL
#define HELLO_API __declspec(dllexport)
#else
#define HELLO_API __declspec(dllimport)
#endif
extern "C"
{
HELLO_API int IntAdd(int , int);
}
CPP文件:
[cpp] view plain 在CODE上查看代碼片派生到我的代碼片//hello.cpp
#define EXPORT_HELLO_DLL
#include "hello.h"
HELLO_API int IntAdd(int a, int b)
{
return a + b;
}
這里有兩個注意點:
(1)弄清楚編譯的時候函數的調用約定採用的__cdecl還是__stdcall,因為根據DLL中函數調用約定方式,Python將使用相應的函數載入DLL。
(2)如果採用C++的工程,那麼導出的介面需要extern "C",這樣python中才能識別導出的函數。
我的工程中採用__cdecl函數調用約定方式進行編譯鏈接產生hello.dll,然後Python中採用ctypes庫對hello.dll進行載入和函數調用:
[python] view plain 在CODE上查看代碼片派生到我的代碼片from ctypes import *
dll = cdll.LoadLibrary('hello.dll');
ret = dll.IntAdd(2, 4);
print ret;
OK,一個小例子已經完成了,如果你感興趣,但還沒試過,那就嘗試一下吧。
示例二
示例一隻是一個"hello world"級別的程序,實際運用中更多的需要傳遞數據結構、字元串等,才能滿足我們的需求。那麼這個示例將展示,如何傳遞數據結構參數,以及如何通過數據結構獲取返回值。
首先編寫DLL工程中的頭文件:
[cpp] view plain 在CODE上查看代碼片派生到我的代碼片//hello.h
#ifdef EXPORT_HELLO_DLL
#define HELLO_API __declspec(dllexport)
#else
#define HELLO_API __declspec(dllimport)
#endif
#define ARRAY_NUMBER 20
#define STR_LEN 20
struct StructTest
{
int number;
char* pChar;
char str[STR_LEN];
int iArray[ARRAY_NUMBER];
};
extern "C"
{
//HELLO_API int IntAdd(int , int);
HELLO_API char* GetStructInfo(struct StructTest* pStruct);}
CPP文件如下:
[cpp] view plain 在CODE上查看代碼片派生到我的代碼片//hello.cpp
#include <string.h>
#define EXPORT_HELLO_DLL
#include "hello.h"
HELLO_API char* GetStructInfo(struct StructTest* pStruct){
for (int i = 0; i < ARRAY_NUMBER; i++)
pStruct->iArray[i] = i;
pStruct->pChar = "hello python!";
strcpy (pStruct->str, "hello world!");
pStruct->number = 100;
return "just OK";
}
GetStructInfo這個函數通過傳遞一個StructTest類型的指針,然後對對象中的屬性進行賦值,最後返回"just OK".
編寫Python調用代碼如下,首先在Python中繼承Structure構造一個和C DLL中一致的數據結構StructTest,然後設置函數GetStructInfo的參數類型和返回值類型,最後創建一個StructTest對象,並將其轉化為指針作為參數,調用函數GetStrcutInfo,最後通過輸出數據結構的值來檢查是否調用成功:
[python] view plain 在CODE上查看代碼片派生到我的代碼片from ctypes import *
ARRAY_NUMBER = 20;
STR_LEN = 20;
#define type
INTARRAY20 = c_int * ARRAY_NUMBER;
CHARARRAY20 = c_char * STR_LEN;
#define struct
class StructTest(Structure):
_fields_ = [
("number", c_int),
("pChar", c_char_p),
("str", CHARARRAY20),
("iArray", INTARRAY20)
]
#load dll and get the function object
dll = cdll.LoadLibrary('hello.dll');
GetStructInfo = dll.GetStructInfo;
#set the return type
GetStructInfo.restype = c_char_p;
#set the argtypes
GetStructInfo.argtypes = [POINTER(StructTest)];objectStruct = StructTest();
#invoke api GetStructInfo
retStr = GetStructInfo(byref(objectStruct));#check result
print "number: ", objectStruct.number;
print "pChar: ", objectStruct.pChar;
print "str: ", objectStruct.str;
for i,val in enumerate(objectStruct.iArray):
print 'Array[i]: ', val;
print retStr;
總結
1. 用64位的Python去載入32位的DLL會出錯
2. 以上只是些測試程序,在編寫Python過程中盡可能的使用"try Except"來處理異常3. 注意在Python與C DLL交互的時候位元組對齊問題4. ctypes庫的功能還有待繼續探索

③ python 怎麼調用c語言介面

ctypes: 可直接調用c語言動態鏈接庫。

使用步驟:

1> 編譯好自己的動態連接庫
2> 利用ctypes載入動態連接庫
3> 用ctype調用C函數介面時,需要將python變數類型做轉換後才能作為函數參數,轉換原則見下圖:

#Step1:test.c#include<stdio.h>

intadd(inta,intb)
{
returna+b;
}#Step2:編譯動態鏈接庫(如何編譯動態鏈接庫在本文不詳解,網上資料一大堆。)gcc-fPIC-sharedtest.c-olibtest.so
#Step3:test.py
fromctypesimport*mylib=CDLL("libtest.so")或者cdll.LoadLibrary("libtest.so")add=mylib.add
add.argtypes=[c_int,c_int]#參數類型,兩個int(c_int是ctypes類型,見上表)
add.restype=c_int#返回值類型,int(c_int是ctypes類型,見上表)
sum=add(3,6)

④ python調用C++,如何傳遞數組指針

很多辦法都可以 如果你的c++對象是已有的代碼,可以用cpython包裝成Python對象,這些cpython包裝的對象有一個指針是指向 你要包裝的c++對象的,然後提供訪問c++對象的方法。比如你一顆樹可以包裝成Python對象,樹節點也包裝成Python對象!

⑤ python怎麼使用指針

python 不像c, 沒辦法直接使用指針。指針就是內存地址。
python中,最接近指針的就是, id() 返回某個對象的唯一id,類似於地址了。

⑥ python使用C函數返回的指針

manage_new_object返回類的動態對象,要返回簡單的指針,把manage_new_object改為return_xxx_pointer,具體名字記不得了,反正有這個模板,查閱boost文檔吧。

⑦ python調用c函數

Python是解釋性語言, 底層就是用c實現的, 所以用python調用C是很容易的, 下面就總結一下各種調用的方法, 給出例子, 所有例子都在ubuntu9.10, python2.6下試過
1. Python 調用 C (base)
想在python中調用c函數, 如這兒的fact
#include <Python.h>

int fact(int n)
{
if (n <= 1)
return 1;
else
return n * fact(n - 1);
}

PyObject* wrap_fact(PyObject* self, PyObject* args)
{
int n, result;

if (! PyArg_ParseTuple(args, "i:fact", &n))
return NULL;
result = fact(n);
return Py_BuildValue("i", result);
}

static PyMethodDef exampleMethods[] =
{
{"fact", wrap_fact, METH_VARARGS, "Caculate N!"},
{NULL, NULL}
};

void initexample()
{
PyObject* m;
m = Py_InitMole("example", exampleMethods);
}

把這段代碼存為wrapper.c, 編成so庫,
gcc -fPIC wrapper.c -o example.so -shared -I/usr/include/python2.6 -I/usr/lib/python2.6/config

然後在有此so庫的目錄, 進入python, 可以如下使用
import example
example.fact(4)

2. Python 調用 C++ (base)
在python中調用C++類成員函數, 如下調用TestFact類中的fact函數,
#include <Python.h>

class TestFact{
public:
TestFact(){};
~TestFact(){};
int fact(int n);
};

int TestFact::fact(int n)
{
if (n <= 1)
return 1;
else
return n * (n - 1);
}

int fact(int n)
{
TestFact t;
return t.fact(n);
}
PyObject* wrap_fact(PyObject* self, PyObject* args)
{
int n, result;

if (! PyArg_ParseTuple(args, "i:fact", &n))
return NULL;
result = fact(n);
return Py_BuildValue("i", result);
}

static PyMethodDef exampleMethods[] =
{
{"fact", wrap_fact, METH_VARARGS, "Caculate N!"},
{NULL, NULL}
};

extern "C" //不加會導致找不到initexample
void initexample()
{
PyObject* m;
m = Py_InitMole("example", exampleMethods);
}

把這段代碼存為wrapper.cpp, 編成so庫,
g++ -fPIC wrapper.cpp -o example.so -shared -I/usr/include/python2.6 -I/usr/lib/python2.6/config

然後在有此so庫的目錄, 進入python, 可以如下使用
import example
example.fact(4)

3. Python 調用 C++ (Boost.Python)
Boost庫是非常強大的庫, 其中的python庫可以用來封裝c++被python調用, 功能比較強大, 不但可以封裝函數還能封裝類, 類成員.
http://dev.gameres.com/Program/Abstract/Building%20Hybrid%20Systems%20with%20Boost_Python.CHN.by.JERRY.htm
首先在ubuntu下安裝boost.python, apt-get install libboost-python-dev
#include <boost/python.hpp>
char const* greet()
{
return "hello, world";
}

BOOST_PYTHON_MODULE(hello)
{
using namespace boost::python;
def("greet", greet);
}

把代碼存為hello.cpp, 編譯成so庫
g++ hello.cpp -o hello.so -shared -I/usr/include/python2.5 -I/usr/lib/python2.5/config -lboost_python-gcc42-mt-1_34_1

此處python路徑設為你的python路徑, 並且必須加-lboost_python-gcc42-mt-1_34_1, 這個庫名不一定是這個, 去/user/lib查

然後在有此so庫的目錄, 進入python, 可以如下使用
>>> import hello
>>> hello.greet()
'hello, world'

4. python 調用 c++ (ctypes)
ctypes is an advanced ffi (Foreign Function Interface) package for Python 2.3 and higher. In Python 2.5 it is already included.
ctypes allows to call functions in dlls/shared libraries and has extensive facilities to create, access and manipulate simple and complicated C data types in Python - in other words: wrap libraries in pure Python. It is even possible to implement C callback functions in pure Python.
http://python.net/crew/theller/ctypes/

#include <Python.h>

class TestFact{
public:
TestFact(){};
~TestFact(){};
int fact(int n);
};

int TestFact::fact(int n)
{
if (n <= 1)
return 1;
else
return n * (n - 1);
}

extern "C"
int fact(int n)
{
TestFact t;
return t.fact(n);
}
將代碼存為wrapper.cpp不用寫python介面封裝, 直接編譯成so庫,
g++ -fPIC wrapper.cpp -o example.so -shared -I/usr/include/python2.6 -I/usr/lib/python2.6/config

進入python, 可以如下使用
>>> import ctypes
>>> pdll = ctypes.CDLL('/home/ubuntu/tmp/example.so')
>>> pdll.fact(4)
12

熱點內容
新一代唐dm哪個配置最劃算 發布:2024-05-02 22:45:16 瀏覽:228
安卓怎麼安裝到sd卡 發布:2024-05-02 22:41:32 瀏覽:223
web聊天源碼 發布:2024-05-02 22:41:29 瀏覽:285
php定時腳本 發布:2024-05-02 22:18:41 瀏覽:312
雲服務可以替代普通伺服器么 發布:2024-05-02 21:57:11 瀏覽:944
wegame與伺服器斷開連接是怎麼回事 發布:2024-05-02 21:55:05 瀏覽:785
zip加密破解 發布:2024-05-02 21:41:23 瀏覽:480
怎麼模擬電腦配置 發布:2024-05-02 21:28:08 瀏覽:784
對一個新編程 發布:2024-05-02 21:20:07 瀏覽:559
華為系統編譯器在哪裡 發布:2024-05-02 21:19:50 瀏覽:86