将 C++ 与 Python 连接起来

Interfacing C++ with Python

我有一个 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

在你的情况下,最好保持简单而不使用绑定生成器,因为你这里只有一个不接收任何参数的简单函数,只是 returns 一个 int。

您的目标可以通过以下方式实现:

cpp_reader.cpp 中,在 reader 定义之前添加以下行:

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++命令行