问题描述
我有一个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++