C ++与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

解决方法

对于您而言,最好使它保持简单而不使用绑定生成器,因为您所拥有的只是一个简单的函数,它不接收任何参数,而只是返回一个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++