接上一期SWIG对复杂数据类型的处理,本期介绍通过SWIG将Python的回调函数正确地传递到C++代码,并由C++调用该回调函数。前面介绍过的一些SWIG基础内容,这里不再重复介绍。
往期推荐:
SWIG-Python与C++交互(二)-复杂数据类型(std::map, 自定义数据类型)
SWIG-Python与C++交互(一)-简单教程
本期主要介绍以下几种回调函数的使用场景:
- C风格的回调函数;
- 仿函数作为回调函数;
- C++多线程调用回调函数。
这三个使用场景,从前往后,由易到难,涉及的技术细节,也由少变多。
00 C风格的回调函数
- data_processor.h文件
class DataProcessor {
public:
DataProcessor() {
}
~DataProcessor() {
}
//定义一个用C风格回调函数作为函数参数的接口
int ProcWithCallback(int data, int (*f)(int)) {
if (f == NULL) {
std::cout << "f == NULL";
return 0;
}
++ data;
data = f(data);
std::cout << "f(data)=" << data << std::endl;
return data;
}
};
以上代码主要是定义一个C++接口,接口函数中包含一个C风格的函数指针,在C++接口内部会调用传入的函数指针。建议将接口定义写在.h文件,接口实现写在.cpp文件。这里为了方便展示,都写在了.h文件中。
- data_processor.i文件
%module py_data_processor
# 通过typemap转换函数指针
%typemap(in) int int (*) (int) {
$1 = (int(*) (int))PyInt_AsLong($input);
}
%{
#include "data_processor.h"
%}
%include "data_processor.h"
.i文件中需要对函数指针进行转换,这里通过SWIG的typemap完成输入参数转换。
- py_main.py文件
# -*- coding: utf-8 -*-
from data_processor import py_data_processor
import ctypes
#定义一个与C语言函数类型‘int(*) (int)’一致的python函数
def simple_func(i):
print("simple_func i=%d" % (i))
i = i+1
return i
def main():
dp = py_data_processor.DataProcessor()
# 定义一个与C语言函数类型‘int(*) (int)’一致的函数类型
py_callback_type = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int)
# 将python函数类型转换为C类型函数指针
f = py_callback_type(simple_func)
f_ptr = ctypes.cast(f, ctypes.c_void_p).value
#调用接口,接口参数包含C类型函数指针

1121

被折叠的 条评论
为什么被折叠?



