1. 程式人生 > >Python與C++之間的相互呼叫例項3: 在Python中呼叫C++的結構體和類

Python與C++之間的相互呼叫例項3: 在Python中呼叫C++的結構體和類

之前在C++中寫的程式,絕大多數都是用類來封裝的。

那麼現在想要在Python中進行呼叫,開始的時候是個頭疼的問題。經過將近一天的摸索學習,大概搞明白了一些。

下面貼出來一個例子看一下。

首先是C++的結構體和類:

#pragma once
#include <string>

// 這個結構體在Python中定義後可以通用
struct struHeadPose
{
    float                            angleX;
    float                            angleY;
    float                            angleZ;
};

// 這個類在Python中定義後可以通用
class pyClass
{
public:
    int a;
    int b;
    int c;
    char* str;
};


// 這是一個功能類
class myClass
{
public:
    myClass();
    ~myClass();
    void setPos(struHeadPose tPos);
    void setPose(float x, float y, float z);
    struHeadPose getPose();
    int LoadModel(std::string tStrName);

    void setPYC(pyClass& tIn);
    void getPYC(pyClass& tOut);

private:
    struHeadPose m_pos;
    std::string m_str;

    pyClass m_pyc;
};

cpp很簡單,可以自己實現一下就行了。

然後將上面的內容匯出到dll中。具體看上一篇:https://blog.csdn.net/sdust_dx/article/details/80606297

#include "FileCpp.h"
#include "PySEGY.h"
#define DLLEXPORT __declspec(dllexport)
#define C_DLL_EXPORT extern "C" __declspec(dllexport)
extern "C"
{
    DLLEXPORT void __stdcall setPos1(struHeadPose tPos);
    DLLEXPORT void __stdcall setPos2(float x, float y, float z);
    DLLEXPORT void __stdcall getPos(struHeadPose& tPos);
    DLLEXPORT int __stdcall loadModel(char* tStrName);

    DLLEXPORT void __stdcall setPYC(pyClass tIn);
    DLLEXPORT void __stdcall getPYC(pyClass& tOut);
}

然後在python中呼叫即可。下面是在python中封裝了對應的類(結構體),即可進行呼叫。

有幾個注意問題我寫在註釋中了。

import ctypes
import sys
sys.path.append('./')

myDll = ctypes.CDLL('./HelloCpp2.dll')
myDll.Hello()
myDll.display()
myDll.display_int(1)

myDll.setPara(1,2)
print('sum=',myDll.getSum())


class structPos(ctypes.Structure): #ctypes 的格式定義結構體
    _fields_ = [("X", ctypes.c_float),("Y", ctypes.c_float),("Z", ctypes.c_float)]

sModelPath = ctypes.c_char_p(b"MyString[Can only contain ASCII literal characters.]") # 使用 ctypes.c_char_p 可以傳遞字串到C++中
ret = myDll.loadModel(sModelPath)
print("load model = ", ret)
tPos0 = structPos(1.0, 2.0, 3.0)
print('tPos0=', str(tPos0))
myDll.setPos1(ctypes.byref(tPos0))  #ctypes 的格式來呼叫tPos0結構體(類)
tPos1 = structPos(0,0,0)
myDll.getPos(ctypes.byref(tPos1))
print(tPos1)

print ('tPos1.X = ', tPos1.X)
print ('tPos1.Y = ', tPos1.Y)
print ('tPos1.Z = ', tPos1.Z)

print ('tPos0.X = ', tPos0.X)
print ('tPos0.Y = ', tPos0.Y)
print ('tPos0.Z = ', tPos0.Z)

print('TEST --- CLASS')

class testClass(ctypes.Structure): #ctypes 的格式定義結構體
    _fields_ = [("X", ctypes.c_float),("Y", ctypes.c_float),("Z", ctypes.c_float), ("str", ctypes.c_char_p)]


tClass1 = testClass(4,5,6,sModelPath)
myDll.setPYC(ctypes.byref(tClass1))

tClass2 = testClass()
myDll.getPYC(ctypes.byref(tClass2))
print ('tClass2.X = ', tClass2.X)
print ('tClass2.Y = ', tClass2.Y)
print ('tClass2.Z = ', tClass2.Z)
print(tClass2.str)