C++类函数封装给python调用,大致分为三个部分,第一部分是把我们的C++类函数等封装成一个dll,即动态库。第二部分是生成一个绑定代码,就是用shiboken2根据我们需要封装暴露的文件,生成pythonC++代码。然后第三部分,就是根据第一和第二部分生成的库和代码,进一步封装成py库。然后python文件直接可以调用该库。具体代码如下,源码用的是python的官方源码。主要讲解每个部分的使用。
源码:
------------------icecream.cpp------------------------------------
#include "icecream.h"
Icecream::Icecream(const std::string &flavor) : m_flavor(flavor) {}
Icecream::~Icecream() {}
const std::string Icecream::getFlavor()
{
return m_flavor;
}
Icecream *Icecream::clone()
{
return new Icecream(*this);
}
-------------------------------------------icecream.h------------------------------------------------------
#ifndef ICECREAM_H
#define ICECREAM_H
#include <string>
#include "macros.h"
class BINDINGS_API Icecream
{
public:
Icecream(const std::string &flavor);
virtual Icecream *clone();
virtual ~Icecream();
virtual const std::string getFlavor();
private:
std::string m_flavor;
};
#endif // ICECREAM_H
--------------------------------------------truck.cpp------------------------------------------------------
#include <iostream>
#include <random>
#include "truck.h"
Truck::Truck(bool leaveOnDestruction) : m_leaveOnDestruction(leaveOnDestruction) {}
Truck::Truck(const Truck &other)
{
for (size_t i = 0; i < other.m_flavors.size(); ++i) {
addIcecreamFlavor(other.m_flavors[i]->clone());
}
}
Truck &Truck::operator=(const Truck &other)
{
if (this != &other) {
clearFlavors();
for (size_t i = 0; i < other.m_flavors.size(); ++i) {
addIcecreamFlavor(other.m_flavors[i]->clone());
}
}
return *this;
}
Truck::~Truck()
{
if (m_leaveOnDestruction)
leave();
clearFlavors();
}
void Truck::addIcecreamFlavor(Icecream *icecream)
{
m_flavors.push_back(icecream);
}
void Truck::printAvailableFlavors() const
{
std::cout << "It sells the following flavors: \n";
for (size_t i = 0; i < m_flavors.size(); ++ i) {
std::cout << " * " << m_flavors[i]->getFlavor() << '\n';
}
std::cout << '\n';
}
void Truck::arrive() const
{
std::cout << m_arrivalMessage;
}
void Truck::leave() const
{
std::cout << "The truck left the neighborhood.\n";
}
void Truck::setLeaveOnDestruction(bool value)
{
m_leaveOnDestruction = value;
}
void Truck::setArrivalMessage(const std::string &message)
{
m_arrivalMessage = message;
}
bool Truck::deliver() const
{
std::random_device rd;
std::mt19937 mt(rd());
std::uniform_int_distribution<int> dist(1, 2);
std::cout << "The truck started delivering icecream to all the kids in the neighborhood.\n";
bool result = false;
if (dist(mt) == 2)
result = true;
return result;
}
void Truck::clearFlavors()
{
for (size_t i = 0; i < m_flavors.size(); ++i) {
delete m_flavors[i];
}
m_flavors.clear();
}
----------------------------------------------truck.h----------------------------------------------------
#ifndef TRUCK_H
#define TRUCK_H
#include <vector>
#include "icecream.h"
#include "macros.h"
class BINDINGS_API Truck {
public:
Truck(bool leaveOnDestruction = false);
Truck(const Truck &other);
Truck& operator=(const Truck &other);
~Truck();
void addIcecreamFlavor(Icecream *icecream);
void printAvailableFlavors() const;
bool deliver() const;
void arrive() const;
void leave() const;
void setLeaveOnDestruction(bool value);
void setArrivalMessage(const std::string &message);
private:
void clearFlavors();
bool m_leaveOnDestruction = false;
std::string m_arrivalMessage = "A new icecream truck has arrived!\n";
std::vector<Icecream *> m_flavors;
};
#endif // TRUCK_H
------------------------------------------bindings.h-----------------------------------------------------
#ifndef BINDINGS_H
#define BINDINGS_H
#include "icecream.h"
#include "truck.h"
#endif // BINDINGS_H
------------------------------------------------macros.h------------------------------------------------
#ifndef MACROS_H
#define MACROS_H
#if defined _WIN32 || defined __CYGWIN__
// Export symbols when creating .dll and .lib, and import them when using .lib.
#if BINDINGS_BUILD
#define BINDINGS_API __declspec(dllexport)
#else
#define BINDINGS_API __declspec(dllimport)
#endif
// Disable warnings about exporting STL types being a bad idea. Don't use this in production
// code.
#pragma warning( disable : 4251 )
#else
#define BINDINGS_API
#endif
#endif // MACROS_H
------------------------------------------bindings.xml------------------------------------------------
<?xml version="1.0"?&g