【笔记-python】C++交互

  1. C调用python

文件名一定不能是test,abc.....系统模块有。

不存在#include <inttypes.h>

屏蔽该行,包含#include <stdint.h>

没有python36_d.lib

pyconfig.h中:

pragma comment(lib,"python36_d.lib")

改为python36.lib

    1. Py文件

文件名MyTestMul

def add(i,j):    

return i+j

    1. c调用

Py_SetPythonHome(L"C:\\py363");

Py_Initialize();

if ( !Py_IsInitialized() )

{

cout<<"Py_Initialize 错误"<<endl;

return;

}

PyObject* model = PyImport_ImportModule("MyTestMul");

if (NULL == model)

{

cout<<"PyImport_ImportModule 错误"<<endl;

return;

}

PyObject* pfun = PyObject_GetAttrString(model,"add");

PyObject* pParm = PyTuple_New(2);

PyTuple_SetItem(pParm, 0, Py_BuildValue("i",3));

PyTuple_SetItem(pParm, 1, Py_BuildValue("i",4));

PyObject* pRetVal = PyEval_CallObject(pfun, pParm);

int retVal = -1;  

int ret = PyArg_Parse(pRetVal, "i", &retVal);

if (0 == ret)

{

cout<<"PyArg_Parse错误"<<endl;

return;

}

//Py_DECREF(pfun);

//Py_DECREF(pParm);

//Py_DECREF(pRetVal);

Py_Finalize();

=====构造参数

PyObject *param = Py_BuildValue("(i,i,i)", 123, 456, 789);//  构造元祖数据

PyObject * pList = PyList_New(0);

for (int i = 0; i < 3; i++)   PyList_Append(pList, Py_BuildValue("i", i));

字符

含义

s或者z

(string) [char *]

将C字符串转换成Python对象,如果C字符串为空,返回NONE。

s#或者z#

(string) [char *, int] :将C字符串和它的长度转换成Python对象,如果C字符串为空指针,长度忽略,返回NONE。

z

(string or None) [char *] :作用同s

ib、l(long)

 (integer) [int] :将一个C类型的int转换成Python int对象。

c

(string of length 1) [char] :将C类型的char转换成长度为1的Python字符串对象。

d或f

(float) [double] :将C类型的double转换成python中的浮点型对象。

O&

(object) [converter, anything] :将任何数据类型通过转换函数转换成Python对象,这些数据作为转换函数的参数被调用并且返回一个新的Python对象,如果发生错误返回NULL。

(items)

(tuple) [matching-items] :将一系列的C值转换成Python元组。

[items]

(list) [matching-items] :将一系列的C值转换成Python列表。

{items}

(dictionary) [matching-items] :将一系类的C值转换成Python的字典,每一对连续的C值将转换成一个键值对。

  1. python使用dll

字符串传递需要转换格式

cstr=str.encode(“gbk”)

cdecl调用方式:

ctypes.cdll.LoadLibrary

Stdcall调用方式:

ctypes.windll.LoadLibrary

    1. 函数调用

extern "C" __declspec(dllexport) char* fun(int *a,char *buf,int bufLen)

{

*a = *a * 10;

strcpy_s(buf, bufLen, "xxxx");

return "abcdef";

}

#coding=utf-8
import ctypes
#加载dll
dl = ctypes.cdll.LoadLibrary(r'C:\DT.dll')

#创建字符串缓冲区
bufLen = 100
strBuf = ctypes.create_string_buffer('\0',bufLen)

#创建int*  byref将数值转换为指针
a = ctypes.c_int(5)
aRef = ctypes.byref(a)

#执行dll中的函数
pchar = dl.fun(aRef,strBuf,bufLen)

#将dll返回的char*进行转换
szbuffer = ctypes.c_char_p(pchar)


print a.value
print szbuffer.value
print strBuf.value

"""
sBuf = '123456789'
pStr = ctypes.c_char_p( )
pStr.value = sBuf
bufLen = len(pStr.value)
"""

    1. 类型映射

ctypes数据类型          C数据类型 
c_char                          char 
c_short                         short 
c_int                             int 
c_long                          long 
c_ulong                        unsign long 
c_float                          float 
c_double                      double 
c_void_p                       void 
对应的指针类型是在后面加上"_p",如int*是c_int_p

    1. 结构体交互

struct  DatStu

{

int    num;

char   val[512];

};

extern "C" __declspec(dllexport) void fun(DatStu *stu)

{

stu->num = 10;

strcpy_s(stu->val, 512, "xxx");

}

class DatStu(ctypes.Structure):
    _fields_ = [ ("num", ctypes.c_int),
              ("val", ctypes.c_char * 512)]


dl = ctypes.cdll.LoadLibrary(r'C:\DT.dll')

dat = DatStu()
dl.fun(ctypes.byref(dat))

print dat.num
print dat.val

  1. c++导出pyd

========dll编写

#include "Python.h"

static PyObject *ex_foo(PyObject *self, PyObject *Argvs)

{

int Argv1(0), Argv2(0);

if (!PyArg_ParseTuple(Argvs, "ii", &Argv1, &Argv2))

{//ii表示解析出来两个int型参数

cout << "parse param failed" << endl;

return NULL;

}

cout << Argv1 << "+ " << Argv2 << " = " << Argv1 + Argv2 << endl;

  Py_INCREF(Py_None);//Py_INCREF增加PyObject对象的引用计数

        //Py_DECREF减小PyObject对象的引用计数

   //为了让Python回收废弃的内存、或者防止Python过早地自动回收内存

//必须用Py_EDCREF和Py_INCREF来控制PyObject的引用计数

return Py_None;

}

static PyMethodDef ModulesMethods[] =

{

{ "fun", ex_foo, METH_VARARGS, "fun() doc string" },

{ NULL, NULL }

//fun是导出函数名

//METH_VARARGS,则用Tuple来传递参数   METH_KEYWORDS,则用Dictionary的Key(键值)来传递参数

//"fun() doc string"  函数的说明字符串。在Python中就是函数的DocString __doc__。

};

static struct PyModuleDef ModuleDesc =

{    PyModuleDef_HEAD_INIT,      

      "Module", //内置的模块名   模块名.__name__来获取这个字符串

     "This module is created by C++. And it Add two Integer s!", //模块的DocString,也可以用模块名.__doc__获得

     - 1, //-1  模块在全局范围

 ModulesMethods

};

PyMODINIT_FUNC PyInit_DllName(void)//生成文件名必须 DllName.pyd

{

    //Py_InitModule("DllName", ModulesMethods);  py2

return PyModule_Create(&ModuleDesc);

}

========使用

import DllName

DllName.fun(1,3)

猜你喜欢

转载自blog.csdn.net/jiyanglin/article/details/81583100
今日推荐