- 数据类型
#include <stdio.h>
#include <Python.h>
using namespace std;
PyObject* none_object(){
Py_RETURN_NONE; // 不需要自己return
}
int main() {
// 初始化Python虚拟机
Py_Initialize();
// 判断Python虚拟机是否成功
if (Py_IsInitialized() == 0){
printf("fal to initialize Python\n");
return -1;
}
printf("server start\n");
//
// 第一种方式
PyObject *py_ival = Py_BuildValue("i", -5987); // Python有符号整型
PyObject *py_ival2 = PyLong_FromLong(-8979);
int ival = PyLong_AsLong(py_ival); // 把Python有字符整型转换成C的有字符整型
int ival2 = PyLong_AsLong(py_ival2); // 把Python有字符整型转换成C的有字符整型
printf("ival = %d, ival2 = %d\n", ival, ival2);
// 第二种方式
PyObject *py_uval = Py_BuildValue("I", 465486); // Python无符号整型
PyObject *py_uval2 = PyLong_FromUnsignedLong(1654864);
unsigned int uval = PyLong_AsUnsignedLong(py_uval); // 把Python无字符整型转换成C的无字符整型
unsigned int uval2 = PyLong_AsUnsignedLong(py_uval2); // 把Python无字符整型转换成C的无字符整型
printf("uval = %u, uval2 = %u\n", uval, uval2);
/
PyObject *py_lval = Py_BuildValue("L", 45648946484984); // Python 长整型
long long c_lval = PyLong_AsLongLong(py_lval); // 转换成C的长整型
printf("clval = %lld\n", c_lval);
// 第二种方式
PyObject *py_lval2 = PyLong_FromLongLong(234234623454525); // PyLong_FromLongLong 使用方法定义一个Python长整型
long long c_lval2 = PyLong_AsLongLong(py_lval2); // 转换成C的长整型
printf("clval2 = %lld\n", c_lval2);
/
// 第一种方式
float fval = 632.045;
PyObject *py_fval = Py_BuildValue("d", fval); // Python 浮点类型
float c_fval = PyFloat_AsDouble(py_fval); // C的浮点类型
printf("fval = %f\n", c_fval);
// 第二种方式
double dval = 48941546.578;
PyObject *py_dval = PyFloat_FromDouble(dval); // Python 浮点类型
double c_dval = PyFloat_AsDouble(py_dval); // C的浮点类型
printf("c_dval = %lf\n", c_dval);
///
bool bval = true; // false 反之
PyObject *py_bval = Py_BuildValue("b", bval); // Python 布尔类型
int c_bval = PyInt_AsLong(py_bval);
printf("c_bval = %d\n", c_bval);
// 第二种方式
bool bval2 = false;
PyObject *py_bval2 = PyBool_FromLong(bval2); // Python 布尔类型
int c_bval2 = PyInt_AsLong(py_bval2);
printf("c_bval2 = %d\n", c_bval2);
/
// 第一种方式
const char *pstr = "this is a test";
PyObject *py_str = Py_BuildValue("s", pstr); // Python 字符串对象
char *c_pstr = PyString_AsString(py_str); // 转成C的字符指针
printf("c_pstr = %s\n", c_pstr);
// 第二种方式
const char *pstr2 = "this is a test1";
PyObject *py_str2 = PyString_FromString(pstr2); // Python 字符串对象
char *c_pstr2 = PyString_AsString(py_str2); // 转成C的字符指针
printf("c_pstr2 = %s\n", c_pstr2);
// 创建一个二进制的字符串对象
// 第一种方式
const int mem_len = 1024;
char *mem = new char[mem_len];
PyObject *py_mem = Py_BuildValue("s#", mem, mem_len); // 1. 数据的类型 2. 指向数据的指针 3. 数据的长度
int c_data_len = PyString_Size(py_mem);
printf("c_data_len = %d\n", c_data_len);
// 第二种方式
PyObject *py_mem2 = PyString_FromStringAndSize(mem, mem_len);
int c_data_len2 = PyString_Size(py_mem2);
printf("c_data_len2 = %d\n", c_data_len2);
const char *p_ustr = "兰玉磊";
PyObject *py_unicode = PyUnicode_FromString(p_ustr); // 把C的字符串转成Python的unicode
// 把unicode转成C的字符串
PyObject *py_utf8 = PyUnicode_AsUTF8String(py_unicode); // 把unicode转成utf-8
const char *c_string = PyString_AsString(py_utf8); // 把utf-8转成c的字符串
printf("c_utf8 = %s\n", c_string);
// 格式化unicode字符串
// 创建一个unicode字符串
PyObject *py_unicode_fmt = PyUnicode_FromFormat("%s%d%s", "我今年", 18, "岁");
// 把unicode转C字符串
PyObject *py_utf8_fmt = PyUnicode_AsUTF8String(py_unicode_fmt);
const char *utf8_fmt = PyString_AsString(py_utf8_fmt);
printf("utf8_fmt = %s\n", utf8_fmt);
//
PyObject *py_ret = none_object();
// 退出Python虚拟机
Py_Finalize();
return 0;
}
server start
ival = -5987, ival2 = -8979
uval = 465486, uval2 = 1654864
clval = 45648946484984
clval2 = 234234623454525
fval = 632.044983
c_dval = 48941546.578000
c_bval = 1
c_bval2 = 0
c_pstr = this is a test
c_pstr2 = this is a test1
c_data_len = 1024
c_data_len2 = 1024
c_utf8 = 兰玉磊
utf8_fmt = 我今年18岁
g++ atest.cc
python-config --cflags
python-config --libs
- 引入类和类中函数
- example.cpp
#include "c_python_utils.h"
#include <stdio.h>
int main(int argc, char const *argv[])
{
init();
char* rlt_char = py_call("hello", "power", "liupan", "()");
finit();
printf("%s\n", rlt_char);
return 0;
}
- c_python_utils.h
#ifndef _DTCORE_C_PYTHON_UTILS_H_
#define _DTCORE_C_PYTHON_UTILS_H_
#include <Python.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif /* C++ */
/**
* 调用python类中的成员函数
* @param module python脚本名称,不含扩展
* @param class_name python类名称
* @param function python类成员函数
* @param format python类函数参数格式
* @return 返回字符串
*/
char* py_call( const char* module, const char* class_name, char* function, char* format, ... )
{
PyObject* pName = NULL;
PyObject* pMod = NULL;
PyObject* pDict = NULL;
PyObject* pClass = NULL;
PyObject* pInstance = NULL;
PyObject* pParam = NULL;
PyObject* pResult = NULL;
// 导入模块
pName = PyString_FromString(module);
pMod = PyImport_Import(pName);
if( !pMod )
{
return "";
}
// 获取模块字典属性
pDict = PyModule_GetDict(pMod);
if ( !pDict )
{
return "";
}
// 通过字典获取模块中的类
pClass = PyDict_GetItemString(pDict, class_name);
if ( !pClass )
{
return "";
}
pInstance = PyInstance_New(pClass, NULL, NULL);
if ( !pInstance )
{
return "";
}
pResult = PyObject_CallMethod(pInstance, function, format);
char *rlt_ch = NULL;
PyArg_Parse( pResult, "s", &rlt_ch );
return rlt_ch;
}
/**
* 一些环境的初始化
*
*/
void init()
{
Py_Initialize();
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");
}
/**
* 逆初始化
*/
void finit()
{
Py_Finalize();
}
#ifdef __cplusplus
} /* extern "C" */
#endif /* C++ */
#endif //_DTCORE_C_PYTHON_UTILS_H_
- hello.py
class power():
def liupan(self):
return "hello world"
- 引用计数
- example.cpp
#include <Python.h>
int main(int argc, char *argv[])
{
PyObject *pName, *pModule, *pFunc;
PyObject *pArgs, *pValue;
int i;
if (argc < 3) {
fprintf(stderr, "Usage: call pythonfile funcname [args]\n");
return 1;
}
Py_Initialize();
pName = PyString_FromString(argv[1]);
pModule = PyImport_Import(pName);
Py_DECREF(pName);
if (pModule != NULL) {
pFunc = PyObject_GetAttrString(pModule, argv[2]);
/* pFunc is a new reference */
if (pFunc && PyCallable_Check(pFunc)) {
pArgs = PyTuple_New(argc - 3);
for (i = 0; i < argc - 3; ++i) {
pValue = PyInt_FromLong(atoi(argv[i + 3]));
if (!pValue) {
Py_DECREF(pArgs);
Py_DECREF(pModule);
fprintf(stderr, "Cannot convert argument\n");
return 1;
}
/* pValue reference stolen here: */
PyTuple_SetItem(pArgs, i, pValue);
}
pValue = PyObject_CallObject(pFunc, pArgs);
Py_DECREF(pArgs);
if (pValue != NULL) {
printf("Result of call: %ld\n", PyInt_AsLong(pValue));
Py_DECREF(pValue);
}
else {
Py_DECREF(pFunc);
Py_DECREF(pModule);
PyErr_Print();
fprintf(stderr, "Call failed\n");
return 1;
}
}
else {
if (PyErr_Occurred())
PyErr_Print();
fprintf(stderr, "Cannot find function \"%s\"\n", argv[2]);
}
Py_XDECREF(pFunc);
Py_DECREF(pModule);
}
else {
PyErr_Print();
fprintf(stderr, "Failed to load \"%s\"\n", argv[1]);
return 1;
}
Py_Finalize(); // Finish the Python Interpreter
return 0;
}
- mul.py
def mul(a,b):
print "Will compute", a, "times", b
c = 0
for i in range(0, a):
c = c + b
return c
./demo mul mul 2 3
Will compute 2 times 3
Result of call: 6
- 构造对象与销毁
main.cpp
#include <Python.h>
#include <iostream>
#include <string>
int main(void) {
Py_Initialize(); // 启动虚拟机
if (!Py_IsInitialized())
return -1;
// 导入模块
PyObject* pModule = PyImport_ImportModule("testpy");
if (!pModule) {
printf("Cant open python file!/n");
return -1;
}
// 模块的字典列表
PyObject* pDict = PyModule_GetDict(pModule);
if (!pDict) {
printf("Cant find dictionary./n");
return -1;
}
// 演示函数调用
PyObject* pFunHi = PyDict_GetItemString(pDict, "sayhi");
PyObject_CallFunction(pFunHi, "s", "lhb");
Py_DECREF(pFunHi);
// 演示构造一个Python对象,并调用Class的方法
// 获取Second类
PyObject* pClassSecond = PyDict_GetItemString(pDict, "Second");
if (!pClassSecond) {
printf("Cant find second class./n");
return -1;
}
//获取Person类
PyObject* pClassPerson = PyDict_GetItemString(pDict, "Person");
if (!pClassPerson) {
printf("Cant find person class./n");
return -1;
}
//构造Second的实例
PyObject* pInstanceSecond = PyInstance_New(pClassSecond, NULL, NULL);
if (!pInstanceSecond) {
printf("Cant create second instance./n");
return -1;
}
//构造Person的实例
PyObject* pInstancePerson = PyInstance_New(pClassPerson, NULL, NULL);
if (!pInstancePerson) {
printf("Cant find person instance./n");
return -1;
}
//把person实例传入second的invoke方法
PyObject_CallMethod(pInstanceSecond, "invoke", "O", pInstancePerson);
//释放
Py_DECREF(pInstanceSecond);
Py_DECREF(pInstancePerson);
Py_DECREF(pClassSecond);
Py_DECREF(pClassPerson);
Py_DECREF(pModule);
Py_Finalize(); // 关闭虚拟机
return 0;
}
testpy.py
#!/usr/bin/python
class Person:
def sayHi(self):
print 'hi'
class Second:
def invoke(self,obj):
obj.sayHi()
def sayhi(name):
print 'hi',name;
导出当前路径 export PYTHONPATH=xxxx:$PYTHONPATH
g++ main.cpp -o main -lpython2.7 -I/usr/include/python2.7
- numpy-C-api
- example_logit.c
#include "Python.h"
#include "math.h"
#include "numpy/ndarraytypes.h"
#include "numpy/ufuncobject.h"
#include "numpy/npy_3kcompat.h"
static PyMethodDef LogitMethods[] = {
{NULL, NULL, 0, NULL}
};
static void double_logit(char **args, npy_intp *dimensions,
npy_intp* steps, void* data)
{
npy_intp i;
npy_intp n = dimensions[0];
char *in = args[0], *out = args[1];
npy_intp in_step = steps[0], out_step = steps[1];
double tmp;
for (i = 0; i < n; i++) {
/*BEGIN main ufunc computation*/
tmp = *(double *)in;
tmp /= 1-tmp;
*((double *)out) = log(tmp);
/*END main ufunc computation*/
in += in_step;
out += out_step;
}
}
/*This a pointer to the above function*/
PyUFuncGenericFunction funcs[1] = {&double_logit};
/* These are the input and return dtypes of logit.*/
static char types[2] = {NPY_DOUBLE, NPY_DOUBLE};
static void *data[1] = {NULL};
#if PY_VERSION_HEX >= 0x03000000
static struct PyModuleDef moduledef = {
PyModuleDef_HEAD_INIT,
"npufunc",
NULL,
-1,
LogitMethods,
NULL,
NULL,
NULL,
NULL
};
PyMODINIT_FUNC PyInit_npufunc(void)
{
PyObject *m, *logit, *d;
m = PyModule_Create(&moduledef);
if (!m) {
return NULL;
}
import_array();
import_umath();
logit = PyUFunc_FromFuncAndData(funcs, data, types, 1, 1, 1,
PyUFunc_None, "logit",
"logit_docstring", 0);
d = PyModule_GetDict(m);
PyDict_SetItemString(d, "logit", logit);
Py_DECREF(logit);
return m;
}
#else
PyMODINIT_FUNC initnpufunc(void)
{
PyObject *m, *logit, *d;
m = Py_InitModule("npufunc", LogitMethods);
if (m == NULL) {
return;
}
import_array();
import_umath();
logit = PyUFunc_FromFuncAndData(funcs, data, types, 1, 1, 1,
PyUFunc_None, "logit",
"logit_docstring", 0);
d = PyModule_GetDict(m);
PyDict_SetItemString(d, "logit", logit);
Py_DECREF(logit);
}
#endif
- setup.py
def configuration(parent_package='', top_path=None):
import numpy
from numpy.distutils.misc_util import Configuration
config = Configuration('.',
parent_package,
top_path)
config.add_extension('npufunc', ['example_logit.c'])
return config
if __name__ == "__main__":
from numpy.distutils.core import setup
setup(configuration=configuration)
- test.py
import numpy as np
import npufunc
npufunc.logit(0.5)
a = np.linspace(0,1,5)
print(a)
print(npufunc.logit(a))