【发布时间】:2020-10-01 16:55:03
【问题描述】:
我有一个 c++ (C++ 17) library 和一个依赖于这个库的函数。我想从 python(python 3) 调用这个函数。怎么办?
我已经阅读了一些使用 swig 和 ctypes 的教程,但我不知道如何使它适用于外部共享库。
详情: 我在 /path/to/header/files 目录中有这个 libclickhouse-cpp-lib.so .so 文件和这个库的头文件。
/*File cpp_reader.h*/
#pragma once
int reader();
/* File cpp_reader.cpp*/
#include <clickhouse/client.h>
#include <iostream>
#include "cpp_reader.h"
using namespace clickhouse;
int reader()
{
Client client(ClientOptions().SetHost("localhost"));
int numrows=0;
client.Select("SELECT count(*) from test.test_table",
[&numrows] (const Block& block)
{
for (size_t i=0;i<block.GetRowCount();++i)
{
numrows+=block[0]->As<ColumnUInt64>()->At(i);
}
}
);
return(numrows);
}
我想从 python 调用这个读取函数。我已经使用 swig 和 ctypes 浏览了一些帖子,但无法弄清楚。如果使用其他任何东西都可以轻松完成,请也提出建议。
其他信息: 这就是我在 C++ 中运行代码的方式
/*File: main.cpp*/
#include <clickhouse/client.h>
#include <iostream>
#include <Python.h>
using namespace clickhouse;
int main()
{
/// Initialize client connection.
Client client(ClientOptions().SetHost("localhost"));
int numrows=0;
client.Select("SELECT count(*) from test.test_table",
[&numrows] (const Block& block)
{
for (size_t i=0;i<block.GetRowCount();++i)
{
numrows+=block[0]->As<ColumnUInt64>()->At(i);
}
}
);
std::cout<<"Number of Rows: "<<numrows<<"\n";
}
编译:
g++ -std=c++1z main.cpp -I/path/to/header/files -I/usr/include/python3.6m/ -L. /path/to/libclickhouse-cpp-lib.so -o outfile
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/so_file/directory
导出 LD_LIBRARY_PATH
/path/to/so_file/directory 包含 libclickhouse-cpp-lib.so
./outfile
【问题讨论】:
-
pybind11 是我经验中最简单的方法。如果您已经在使用 Boost,boost.python 也不错。我不推荐
ctypes,除非你只是在业余爱好项目上乱搞,我不推荐swig,除非你需要将你的C++暴露给Python之外的一堆其他语言。 -
我看不出
cpp_reader.h到#include <clickhouse/client.h>甚至iostream的理由。我建议您删除它们以减少对任何绑定生成器的混淆
标签: c++ python-3.x ctypes swig boost-python