将 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++
命令行
我有一个 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++
命令行