将 C++ 与 Python 连接
Posted
技术标签:
【中文标题】将 C++ 与 Python 连接【英文标题】:Interfacing C++ with Python 【发布时间】: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
的理由。我建议您删除它们以减少对任何绑定生成器的混淆
你试过google.com/search?q=how+to+write+a+python+library+in+c%2B%2B 吗?
【参考方案1】:
在你的情况下,最好保持简单,不要使用绑定生成器,因为你这里只有一个简单的函数,它不接收任何参数,只返回一个 int。
您的目标可以通过以下方式实现:
在cpp_reader.cpp
中,在阅读器定义之前添加以下行:
extern "C" __attribute__ ((visibility ("default")))
int reader()
....
现在从 Python 你可以简单地做:
from ctypes import cdll
import os
lib = cdll.LoadLibrary(os.path.abspath("libclickhouse-cpp-lib.so"))
num_rows = lib.reader()
另外不要忘记在编译共享对象时将-shared
添加到g++
命令行
【讨论】:
以上是关于将 C++ 与 Python 连接的主要内容,如果未能解决你的问题,请参考以下文章
UDP 连接没有收到来自服务器的任何回复 - Python(也可能是使用 boost 的 c++)
如何编译多个 C++ 文件以将它们与 Python ctypes 一起使用?