当前位置:首页 » 编程语言 » 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

热点内容
英雄联盟技能脚本 发布:2024-05-17 14:59:41 浏览:444
全名k歌安卓手机里面怎么录屏 发布:2024-05-17 14:40:07 浏览:180
常用数据库介绍 发布:2024-05-17 14:31:38 浏览:504
中孚存储介质信息消除工具 发布:2024-05-17 14:31:33 浏览:589
服务器访问ip如何调转主页 发布:2024-05-17 14:30:33 浏览:789
好玩的解压化妆小游戏 发布:2024-05-17 14:10:57 浏览:127
交通银行怎么登陆不了密码 发布:2024-05-17 13:54:48 浏览:543
安卓如何自动连接无线 发布:2024-05-17 13:53:51 浏览:262
python的urlparse 发布:2024-05-17 13:44:20 浏览:769
linux命令全称 发布:2024-05-17 12:07:54 浏览:110