- C调用python
文件名一定不能是test,abc.....系统模块有。
不存在#include <inttypes.h>
屏蔽该行,包含#include <stdint.h>
没有python36_d.lib
pyconfig.h中:
pragma comment(lib,"python36_d.lib")
改为python36.lib
-
- Py文件
文件名MyTestMul
def add(i,j):
return i+j
-
- 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 |
i或b、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值将转换成一个键值对。 |
- python使用dll
字符串传递需要转换格式
cstr=str.encode(“gbk”)
cdecl调用方式:
ctypes.cdll.LoadLibrary
Stdcall调用方式:
ctypes.windll.LoadLibrary
-
- 函数调用
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)
"""
-
- 类型映射
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
-
- 结构体交互
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
- 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)