6

我正在尝试将 c++ 代码包装到 python 中,只有一个类可以导出两个函数。我编译到 map.so 并且当我尝试import map 得到像噪音这样的错误时

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: ./map.so: undefined symbol: _ZTIN5noise6module6ModuleE

我的 c++ 目录看起来像(噪音是下载的源代码,所有代码都在 src 中)

/ map.cpp
  real_map.h
  real_map.cpp
  noise/
       src/
          .h and .cpp and new directory

我的 CMakeLists.txt 看起来像

project (map)
cmake_minimum_required(VERSION 2.8)

find_package(PythonLibs)
include_directories (${PYTHON_INCLUDE_DIRS})

find_package(Boost 1.45.0 COMPONENTS python)
include_directories (${Boost_INCLUDE_DIRS})


add_library (
    map SHARED  
    WrappedMediumMapTile.cpp
)

target_link_libraries (medium_map
    boost_python
    ${PYTHON_LIBRARIES}
    ${Boost_LIBRARIES}
)

有谁知道有什么问题?

我要包装的 .cpp 类

#include <list>
#include <iostream>
#include <vector>
#include <utility>
#include <map>

#include "noise/src/noise.h"
#include "noiseutils/noiseutils.h"

class MapTile
{
public:
    MapTile(float x1, float y1, float x2, float y2);
    ~MapTile();
    void genHeightMaps(int resX, int resY);


    bool isPassable(float x, float y);
    bool isBuildable(float x, float y);


protected:
    float parentX1;
    float parentY1;
    float parentX2;
    float parentY2;

private:
    noise::module::RidgedMulti baseMountainTerrain;
    noise::module::ScaleBias mountainTerrain;
    noise::module::Billow baseFlatTerrain;
    noise::module::ScaleBias flatTerrain;
    noise::module::Perlin lowFreqBaseTerrainType;
    noise::module::Perlin mediumFreqBaseTerrainType;
    noise::module::Perlin highFreqBaseTerrainType;
    noise::module::Select baseTerrainType;
    noise::module::ScaleBias terrainType;
    noise::module::Const zero;
    noise::module::Perlin highHigh;
    noise::module::Select finalTerrain;
    noise::module::Select goldWoodDeposits;
    noise::utils::NoiseMap heightMapTerrain;
    noise::utils::NoiseMap heightMapGoldWood;
    noise::utils::Image image;
};

和我的包裹蟒蛇

#include <boost/python.hpp>

#include "MapTile.h"
#include "noise/src/noise.h"
#include "noiseutils/noiseutils.h"

using namespace boost::python;

BOOST_PYTHON_MODULE(map) // module name
{
     class_<MapTile>("MapTile", init<float, float, float, float>())
        .def("isPassable", &MapTile::isPassable)
        .def("isBuildable", &MapTile::isBuildable);
};

噪声库从 http://sourceforge.net/projects/libnoise/files/libnoise%20sources/1.0.0/libnoisesrc-1.0.0.zip/download?use_mirror=garr&download=下载 并使用噪声文件夹

4

2 回答 2

0

当我没有确保适当的范围时,我遇到了类似的错误。看起来您正在导入很多标题,请再次检查。

于 2014-07-04T12:09:33.590 回答
0

在 python 中导入一些东西,运行一些其他代码,在这种情况下,它正在加载和执行一些 C++ 代码。

当您在 linux 中加载库 (as .so) 或运行可执行文件时,它会在它链接到的所有共享对象中查找符号。在编译和链接可执行文件或库时,它会在链接时检查列出的目录中的所有符号,以查找这些共享对象。

但是还有另一个概念是那些共享对象的路径。当您对某些库有一些依赖项时,不仅.so可以存储这些文件的名称,而且可以将它们的路径存储在您的.so或可执行文件中。它更像是查找依赖项的路径列表,而不是每个共享对象的路径。

您可以使用 . 检查二进制文件的路径和库ldd

如果在编译过程中由于某种原因找到了这些.so文件,但它们的路径未添加到库/可执行文件中,那么在加载库或运行可执行文件时,您将收到无法找到符号的错误。您可以使用此开关gcc添加二进制文件的路径:

-Wl,-rpath,your_path

你可以在这里看到更多信息

我觉得这可能是您的问题,因为您只是在 CMAKE 中设置 inlude_dir 变量。

于 2014-01-13T09:06:21.523 回答