library.h
#ifndef PYCTYPESDEMO_LIBRARY_H
#define PYCTYPESDEMO_LIBRARY_H
extern "C" {
typedef int (*callback_example_t)(int*, int);
void hello();
int call_callback(callback_example_t func, int *pa, int pb);
};
#endif //PYCTYPESDEMO_LIBRARY_H
library.cpp
#include "library.h"
#include <iostream>
void hello() {
std::cout << "Hello, World!" << std::endl;
}
int call_callback(callback_example_t func, int *pa, int b)
{
int ret = -1;
std::cout << "call_callback in C++" << std::endl;
if (func != nullptr) {
ret = func(pa, b);
}
std::cout << "call_callback in C++ return " << ret << std::endl;
return ret;
}
CMakefiles.txt
cmake_minimum_required(VERSION 3.17)
project(PyCtypesDemo)
set(CMAKE_CXX_STANDARD 14)
set(PYTHON_ROOT "/Users/***/.pyenv/versions/3.7.0")
include_directories(${PYTHON_ROOT}/include/python3.7m)
link_directories(${PYTHON_ROOT}/lib)
add_library(PyCtypesDemo SHARED library.cpp library.h)
target_link_libraries(PyCtypesDemo libpython3.7m.a)
demo.py
from ctypes import *
LIB_PATH = '/Users/***/CLionProjects/PyCtypesDemo/cmake-build-debug/libPyCtypesDemo.dylib'
libcpp = cdll.LoadLibrary(LIB_PATH)
libcpp.hello()
CMPFUNC = CFUNCTYPE(c_int, POINTER(c_int), c_int)
def callback_example_python(a, b):
i = 0
print('callback_example_python ', b, ' count')
while i < b:
print('callback_example_python ', a[i], b)
i=i+1
print('callback_example_python return ', b)
return b
callback_func = CMPFUNC(callback_example_python)
INPUT = c_int * 4
input = INPUT()
input[0] = 11
input[1] = 2
input[2] = 3
input[3] = 4
print('start call callback python->c++')
ret = libcpp.call_callback(callback_func, input, 4)
print('ret=', ret)
运行日志
***@PC001 PyCtypesDemo % python3 api.py
Hello, World!
start call callback python->c++
call_callback in C++
callback_example_python 4 count
callback_example_python 11 4
callback_example_python 2 4
callback_example_python 3 4
callback_example_python 4 4
callback_example_python return 4
call_callback in C++ return 4
ret= 4
***@PC001 PyCtypesDemo %