同Python调C语言方式一样,python调C++同样是三种方式,但是python无法直接调用C++的函数,需要通过extend "C"进行转换。这篇笔记仍然记录ctypes的方式,关于Python扩展模块的方式随后整理再发。
废话不多说,直接拍demo代码,笔记都在代码里了。
# apt install python-ctypeslib
import ctypes
## @1 基础
'''
python 无法直接调到C++的方法,需要通过extend "C" {}进行转换
功能:打印:“hello world”
源码:
#include <iostream>
#include <stdio.h>
// C++
void cpp_hello(){
std::cout << "hello world" << std::endl;
return;
}
//转C
extern "C" {
void hello(){
cpp_hello();
return ;
}
}
编译:g++ -o ./lib/libhelloworld.so -shared -fPIC ./src/helloworld.cpp
'''
def call_helloworld():
print "========== @1 In function call_libhelloword =========="
## 使用ctypes 模块加载动态链接库
loadlib = ctypes.cdll.LoadLibrary
pycall = loadlib("./lib/helloworld.so")
pycall.hello()
return
# @2 关于 Python调C++类的成员函数——>使用上下文
'''
功能:创建C++对象、调用成员show()访问私有成员变量的值、通过成员方法modefy()修改私有成员变量的值
代码:
#include <stdio.h>
#include <iostream>
using namespace std;
class Test{
private:
int pri_num1 ;
int pri_num2 ;
public:
Test();
void modefy(int num1, int num2);
void show();
};
Test::Test(){
this->pri_num1 = -1;
this->pri_num2 = -1;
}
void Test::modefy(int num1 ,int num2){
cout << "C++ log |---- in function Test(int num1 ,int num2) ----" << endl;
cout<<"C++ log |recive: num1:"<< num1 <<" num2:"<< num2 <<endl;
this->pri_num1 = num1;
this->pri_num2 = num2;
cout << "C++ log |----------------- out ------------------------" << endl;
return;
}
void Test::show(){
cout << "C++ log |pri_num1:" << this->pri_num1 << endl;
cout << "C++ log |pri_num2:" << this->pri_num2 << endl;
return ;
}
extern "C" {
void getContext(void* &context){
context = (void*)(new Test());
cout <<"C log| context:"<< context << endl;
return;
}
void show(void * context){
if (NULL == context){
cout << "C log|context is NULL" << endl;
return;
}
((Test*)context) -> show();
return;
}
void modefy(void* context,int x, int y){
if (NULL == context){
cout << "C log|context is NULL" << endl;
return;
}
((Test*)context) -> modefy(x ,y);
return;
}
}
编译:g++ -o ./lib/libcontext.so -shared -fPIC ./src/context.cpp
'''
def call_context():
print "========== @2 In function call_context =========="
loadlib = ctypes.cdll.LoadLibrary
pycall = loadlib("./lib/libcontext.so")
p_context = ctypes.c_void_p(None)
pycall.getContext.argtypes = (ctypes.POINTER(ctypes.c_void_p),)
pycall.getContext(ctypes.byref(p_context))
print "context:",p_context
pycall.show.argtypes = (ctypes.c_void_p,)
pycall.show(p_context)
pycall.modefy.argtypes = (ctypes.c_void_p,ctypes.c_int,ctypes.c_int)
pycall.modefy(p_context,192,168)
pycall.show.argtypes = (ctypes.c_void_p,)
pycall.show(p_context)
pass
if __name__ == "__main__":
call_helloworld()
'''
========== @1 In function call_libhelloword ==========
hello world
'''
call_context()
'''
========== @2 In function call_context ==========
C log| context:0x211caf0
context: c_void_p(34720496)
C++ log |pri_num1:-1
C++ log |pri_num2:-1
C++ log |---- in function Test(int num1 ,int num2) ----
C++ log |recive: num1:192 num2:168
C++ log |----------------- out ------------------------
C++ log |pri_num1:192
C++ log |pri_num2:168
'''