python借助pybind11调用c++(自定义结构体)

安装pybind11

方法1 源代码安装

git clone https://github.com/pybind/pybind11
cd pybind11 && mkdir build && cd build && cmake ..  
make install #如果不可以,就 sudo make install

方法 2 直接使用pip 安装

写对应的 C++ 代码

#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <fstream>
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <unordered_map>
#include <iterator>

namespace py = pybind11;

struct MeshData { //自定义数据结构
    std::vector<std::vector<double>> vertices;
    std::vector<std::vector<double>> colors;
    std::vector<std::vector<double>> vertices_norms;
    std::vector<std::vector<int>> faces;
    std::vector<int> sem;
    std::unordered_map<int, std::string> color_map_str;

};

MeshData load_obj(const std::string& model_sem_path) {
    std::ifstream fin(model_sem_path);
    if (!fin.is_open()) {
        throw std::runtime_error("Unable to open file: " + model_sem_path);
    }   

    std::vector<std::vector<std::string>> fields_list;
    std::vector<std::vector<double>> vertices;
    std::vector<std::vector<double>> colors;
    std::vector<std::vector<double>> vertices_norms;
    std::vector<std::vector<int>> faces;
    std::vector<int> sem;
    std::unordered_map<int, std::string> color_map_str;

    std::string line;0
    while (std::getline(fin, line)) {
        std::istringstream iss(line);
        std::vector<std::string> fields(std::istream_iterator<std::string>{iss},
                                        std::istream_iterator<std::string>());
        fields_list.push_back(fields);
        
        if (fields[0] == "v") {
            vertices.push_back({std::stod(fields[1]), std::stod(fields[2]), std::stod(fields[3])});
            colors.push_back({std::stod(fields[4]), std::stod(fields[5]), std::stod(fields[6])});
            sem.push_back(std::stoi(fields.back()));
            int out_id = std::stoi(fields.back());
            if (color_map_str.find(out_id) == color_map_str.end()) {
                color_map_str[out_id] = fields[4] + ' ' + fields[5] + ' ' + fields[6];
            }
        } else if (fields[0] == "vn") {
            vertices_norms.push_back({std::stod(fields[1]), std::stod(fields[2]), std::stod(fields[3])});
        } else if (fields[0] == "f") {
            faces.push_back({std::stoi(fields[1]) - 1, std::stoi(fields[2]) - 1, std::stoi(fields[3]) - 1});
        }
    }

    MeshData model_data;
    model_data.vertices = vertices;
    model_data.colors = colors;
    model_data.vertices_norms = vertices_norms;
    model_data.faces = faces;
    model_data.sem = sem;
    model_data.color_map_str = color_map_str;

    return model_data;
}

PYBIND11_MODULE(py2cpp, m) {
    m.def("load_obj", &load_obj, "Load obj function");
    py::class_<MeshData>(m, "MeshData")
        .def(py::init<>())
        .def_readwrite("vertices", &MeshData::vertices)
        .def_readwrite("colors", &MeshData::colors)
        .def_readwrite("vertices_norms", &MeshData::vertices_norms)
        .def_readwrite("faces", &MeshData::faces)
        .def_readwrite("sem", &MeshData::sem)
        .def_readwrite("color_map_str", &MeshData::color_map_str);
}

编译代码

mkdir build
cd build
cmake ..
make 

写 Python 代码

from build import py2cpp #导入对应的 so 文件


model_sem_path = "model.obj"
model_data = py2cpp.load_obj(model_sem_path)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python调用C++函数并返回结构体,可以通过使用ctypes库来实现。下面是一个示例代码,展示了如何在Python调用一个返回结构体C++函数: 假设我们有一个C++函数,它返回一个结构体类型`MyStruct`: ```c++ #include <iostream> struct MyStruct { int my_int; float my_float; char my_string[256]; }; MyStruct get_struct() { MyStruct s; s.my_int = 123; s.my_float = 3.14; strcpy(s.my_string, "Hello, C++!"); return s; } ``` 现在,我们可以通过使用ctypes库来在Python调用这个函数并获取返回的结构体。下面是示例代码: ```python import ctypes # 加载C++编译后的动态链接库 lib = ctypes.cdll.LoadLibrary('./libexample.so') # 定义结构体类型 class MyStruct(ctypes.Structure): _fields_ = [ ("my_int", ctypes.c_int), ("my_float", ctypes.c_float), ("my_string", ctypes.c_char * 256) ] # 设置函数的返回类型为MyStruct类型 lib.get_struct.restype = MyStruct # 调用C++函数并获取返回的结构体 result = lib.get_struct() # 输出结构体的成员变量 print(result.my_int) print(result.my_float) print(result.my_string.decode()) ``` 在上面的示例代码中,我们首先使用`cdll.LoadLibrary()`函数加载C++编译后的动态链接库。接着,我们定义了一个结构体类型`MyStruct`,并使用`_fields_`属性来定义结构体的成员变量列表。然后,我们使用`restype`属性将C++函数的返回类型设置为`MyStruct`类型。 最后,我们调用C++函数`get_struct()`并获取返回的结构体,将其赋值给变量`result`。我们可以通过访问结构体对象的成员变量来获取它们的值,使用`.decode()`方法将`my_string`成员变量从`bytes`类型转换为字符串类型并输出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值