3

我正在尝试使用 Boost.Python 为模板库的某个实例化构建一个小的 Python 扩展。这个库广泛使用了 CGAL 库,它与 CMake 集成得相当好,因此我将其用于我的项目。

这是我的模块(python_export.cpp)的代码:

#include <boost/python.hpp>
#include <CGAL/Exact_spherical_kernel_3.h>
#include "Sphere_intersecter.h" // header-only

typedef CGAL::Exact_spherical_kernel_3 SK;
template class Sphere_intersecter<SK>; // explicit for "-fno-implicit-templates"
typedef Sphere_intersecter<SK> SI;

BOOST_PYTHON_MODULE(thickness_diag)
{
    using namespace boost::python;
    class_<SI>("SphereIntersecter", no_init)
        .def("add_sphere", &SI::add_sphere)
    ;
}

和 CMakeLists.txt:

cmake_minimum_required(VERSION 2.6.2)
project(ThicknessDiag-Python)

# CGAL
find_package(CGAL REQUIRED)
include(${CGAL_USE_FILE})

# Boost
find_package(Boost REQUIRED COMPONENTS python)
find_package(PythonLibs 2.7 REQUIRED)
include_directories(${Boost_INCLUDE_DIRS})
include_directories(${PYTHON_INCLUDE_DIRS})

# Shared library
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-implicit-templates")
set(ThicknessDiag-Python "thickness_diag")
add_library(${ThicknessDiag-Python} SHARED python_export.cpp)
set_target_properties(${ThicknessDiag-Python} PROPERTIES PREFIX "")
target_link_libraries(${ThicknessDiag-Python}
    ${PYTHON_LIBRARIES} ${Boost_LIBRARIES}
    ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES})

编译命令的详细输出:

[100%] Building CXX object CMakeFiles/thickness_diag.dir/python_export.cpp.o
/usr/bin/c++ -Dthickness_diag_EXPORTS -DCGAL_USE_MPFR -DCGAL_USE_GMP -frounding-math -fno-implicit-templates -O3 -DNDEBUG -fPIC -isystem /usr/local/include -I/usr/include/python2.7 -o CMakeFiles/thickness_diag.dir/python_export.cpp.o -c /home/jmcomets/ThicknessDiag/tests/python_export.cpp
Linking CXX shared library thickness_diag.so
/usr/bin/c++ -fPIC -frounding-math -fno-implicit-templates -O3 -DNDEBUG -shared -Wl,-soname,thickness_diag.so -o thickness_diag.so CMakeFiles/thickness_diag.dir/python_export.cpp.o -L/usr/local/lib -lmpfr -lgmp /usr/local/lib/libCGAL.so /usr/local/lib/libboost_thread.so -lpthread /usr/local/lib/libboost_system.so -lpython2.7 /usr/local/lib/libboost_python.so /usr/local/lib/libCGAL.so /usr/local/lib/libboost_thread.so -lpthread /usr/local/lib/libboost_system.so -lpython2.7 /usr/local/lib/libboost_python.so -Wl,-rpath,/usr/local/lib 

导入共享库的输出:

$ python -c 'import thickness_diag'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: ./thickness_diag.so: undefined symbol: _ZN5boost6python9converter6detail15registered_baseIRVK18Sphere_intersecterIN4CGAL18Spherical_kernel_3INS5_9CartesianINS5_4GmpqEEENS5_32Algebraic_kernel_for_spheres_2_3IS8_EEEEEE10convertersE
$ nm thickness_diag.so | grep _ZN5boost6python9converter6detail15registered_baseIRVK18Sphere_intersecterIN4CGAL18Spherical_kernel_3INS5_9CartesianINS5_4GmpqEEENS5_32Algebraic_kernel_for_spheres_2_3IS8_EEEEEE10convertersE
                 U _ZN5boost6python9converter6detail15registered_baseIRVK18Sphere_intersecterIN4CGAL18Spherical_kernel_3INS5_9CartesianINS5_4GmpqEEENS5_32Algebraic_kernel_for_spheres_2_3IS8_EEEEEE10convertersE

在过去的两天里,我一直在为此苦苦挣扎,任何帮助都会很棒!:)

编辑: ldd 的输出

$ ldd thickness_diag.so
    linux-vdso.so.1 =>  (0x00007fffdfdff000)
    libgmp.so.10 => /usr/lib/x86_64-linux-gnu/libgmp.so.10 (0x00007fd91eadf000)
    libCGAL.so.10 => /usr/local/lib/libCGAL.so.10 (0x00007fd91e8b4000)
    libboost_thread.so.1.55.0 => /usr/local/lib/libboost_thread.so.1.55.0 (0x00007fd91e699000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fd91e47c000)
    libboost_system.so.1.55.0 => /usr/local/lib/libboost_system.so.1.55.0 (0x00007fd91e278000)
    libpython2.7.so.1.0 => /usr/lib/libpython2.7.so.1.0 (0x00007fd91dd79000)
    libboost_python.so.1.55.0 => /usr/local/lib/libboost_python.so.1.55.0 (0x00007fd91db2c000)
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fd91d829000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fd91d612000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd91d253000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fd91cf57000)
    librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fd91cd4e000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fd91ef85000)
    libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fd91cb37000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fd91c933000)
libutil.so.1 => /lib/x86_64-linux-gnu/libutil.so.1 (0x00007fd91c72f000)
4

2 回答 2

3

好吧,我想通了。事实证明,该选项-fno-implicit-templates阻止了 boost 进行正常的模板实例化(这实际上非常明显)。

然后我又回到了一个我认为已修复的错误:undefined symbol: _ZN18Sphere_intersecterIN4CGAL18Spherical_kernel_3INS0_9CartesianINS0_4GmpqEEENS0_32Algebraic_kernel_for_spheres_2_3IS3_EEEEEC1ERKS8_ (./thickness_diag.so)

其中,当通过c++filt翻译时,给出:Sphere_intersecter<...> >::Sphere_intersecter(Sphere_intersecter<...> const&)

未实现的复制构造函数(不可复制的类)......

解决方案是删除添加boost::noncopyable参数到boost::python::class_

#include <boost/python.hpp>
#include <CGAL/Exact_spherical_kernel_3.h>
#include "Sphere_intersecter.h"

typedef CGAL::Exact_spherical_kernel_3 SK;
template class Sphere_intersecter<SK>;
typedef Sphere_intersecter<SK> SI;

BOOST_PYTHON_MODULE(thickness_diag)
{
    using namespace boost::python;
    class_<SI, boost::noncopyable>("SphereIntersecter")
        .def("add_sphere", &SI::add_sphere)
    ;
}
于 2013-07-23T13:01:52.917 回答
1
$man nm
...
"U" The symbol is undefined.

这意味着什么?它不在那里

试试ldd你的so. 这将告诉您它使用的所有库。然后,您需要确保所有库都已打开LD_LIBRARY_PATH

于 2013-07-23T09:29:18.790 回答