1. 程式人生 > >python調C++的方式——1.

python調C++的方式——1.

同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
  '''