4

Boost::Python を使用していくつかの C++ ライブラリとやり取りしたい python プロジェクトがあります。他の人が同じプロジェクト内で python/boost::python/C++ コードを整理する方法を知りたいです。

組織とは、ファイル/ディレクトリ構造、ビルド手順などを意味します。

4

2 に答える 2

1

以下では、pif は Python Interface を表します。まず、conv_pif.hpp という汎用ヘッダー ファイルを用意しました。このファイルには、Boost ヘッダーや C++ Std Library ヘッダーなどが含まれています。次に、boost python モジュールごとに、string_pif.cpp という形式のファイル (ここではサンプル モジュール genocpp に対応) を用意します。ここで、string はおおよそモジュールの名前に対応します。

****************************************************************************************
geno_pif.cpp
****************************************************************************************
#include "conv_pif.hpp"
#include <boost/python.hpp>
#include "geno.hpp"

void export_cppvec_conv();

void export_geno()
{
  boost::python::def("write_geno_table_affy6_to_file", write_geno_table_affy6_to_file);
}

BOOST_PYTHON_MODULE(genocpp)
{
  export_geno();
  export_cppvec_conv();
}
*****************************************************************************************

関数 export_cppvec_conv は、C++ ベクトルから Python リストへの (テンプレート化された) コンバーターに対応します。ファイル cppvec_conv_pif.cpp に実際のコンバーターがあります。特に、これはテンプレートのインスタンス化を使用する export_cppvec_conv を定義するため、geno_pif.cpp に含めずに済むようになります。説明のために、export_cppvec_conv の内容は次のとおりです。cppvec_to_python_list と cppvec_from_python_list は、cppvec_conv_pif.cpp の本体で定義されています。

******************************************
cppvec_conv_pif.cpp (extract)
******************************************
void export_cppvec_conv()
{
  boost::python::to_python_converter<vector<double>, cppvec_to_python_list<double> >();
  cppvec_from_python_list<double>();

  boost::python::to_python_converter<vector<int>, cppvec_to_python_list<int> >();
  cppvec_from_python_list<int>();

  boost::python::to_python_converter<vector<string>, cppvec_to_python_list<string> >();
  cppvec_from_python_list<string>();
}
******************************************

genocpp モジュールに必要な数のコンバーターを追加できます。それからもちろん、geno.hpp に遺伝子関数のヘッダーがあります。最後に、すべてをリンクするSconsファイルがあります

******************************************
Sconstruct
******************************************
#!/usr/bin/python

import commands, glob, os

# Common file, for both executables and Python Interface
common_files = """geno print"""

def pyversion():
    pystr = commands.getoutput('python -V')
    version = pystr.split(' ')[1]
    major, minor = version.split('.')[:2]
    return major + '.' + minor

common_base = Split(common_files)
common = [f + ".cpp" for f in common_base]

# For Python interface only
pif_conv = Split("cppvec_conv cppmap_conv cppset_conv")
pif_conv_files = [t+"_pif.cpp" for t in pif_conv]

pif = Split("geno")
pif_files = [t+"_pif.cpp" for t in pif]

# Boost Python Environment
boost_python_env = Environment(
    CPPPATH=["/usr/include/python"+pyversion(), "."],
    CXXFLAGS='-ftemplate-depth-100 -fPIC -Wall -Werror -pedantic -pipe -O3 -ffast-math -march=opteron',
    #CXXFLAGS='-ftemplate-depth-100 -fPIC -Wall -pedantic -O0 -g',
    CPPDEFINES=['BOOST_PYTHON_DYNAMIC_LIB'],
    LIBPATH=["/usr/lib/python"+pyversion()+"/config"],
    LIBS=["python"+pyversion(), "m", "boost_python"],
    SHLIBPREFIX="", #gets rid of lib prefix
    SHOBJSUFFIX = ".bpo"
)

boost_python_env.SharedLibrary(target='genocpp', source = common + pif_conv_files + pif_files)

この場合、モジュールは 1 つしかないため、pif_files には geno_pif.cpp のみが含まれます。それ以外の場合は、モジュールに必要なものだけを選択します。うーん、実際の例をどこかにアップロードするのが最も簡単かもしれません。誰かがもっと詳細に興味があるなら、私はこれを編集できると思いますか?

よろしく、 ファヒーム

于 2011-01-26T13:05:55.727 に答える
0

これについて直接アドバイスすることはできませんが、paludisと呼ばれる Gentoo のパッケージ マネージャーがこれを行います。私が知る限り、その開発者は非常に有能なので、そのソースはこれを行う方法の良い例になるかもしれません。

ただし、個人的には Boost Python をお勧めしません。cython、SWIG、SIP などの他のバインディング ツールと比較して、非常に遅く、メモリを消費すると言われています。

于 2011-01-23T16:28:56.553 に答える