问题
I am trying to wrap c++ code into python, just one class to export with two functions.
I compiled to to map.so and when I try to import map
get error like noise
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: ./map.so: undefined symbol: _ZTIN5noise6module6ModuleE
My c++ directory looks like (noise is dowwnloaded source code and all code is inside src)
/ map.cpp
real_map.h
real_map.cpp
noise/
src/
.h and .cpp and new directory
my CMakeLists.txt looks like
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}
)
Does anyone have a clue what is a problem ?
My .cpp class which I want to wrap
#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;
};
and my wrap python
#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);
};
Noise library is downloaded from http://sourceforge.net/projects/libnoise/files/libnoise%20sources/1.0.0/libnoisesrc-1.0.0.zip/download?use_mirror=garr&download= and used noise folder
回答1:
Importing something in python, runs some other codes, and in this case it's loading and executing some C++ code.
When you load a library (as .so
) or run an executable in linux, it looks for symbols in all the shared objects that it's linked to. When the executable or the library is being compiled and linked, it checks for all the symbols while linking, in the directories that are listed for looking for those shared objects.
But there is also another concept which is the path of those shared objects. When you have some dependencies to some libraries, not only the name of those .so
files can be stored, but also the path to them can be stored in your .so
or executable. It's more like a list of paths to look for dependencies rather than a per-shared-object path.
You can check for the paths and libraries of you binary using ldd
.
If during the compilation for some reason finds those .so
files, but the path to them is not added to the library/executable, then while loading the library or running the executable you will get an error for not being able to find a symbol. You can use this switch in gcc
to add a path to the binary:
-Wl,-rpath,your_path
And you can see more info here
I feel like this might be your problem, cause you are only setting the inlude_dir variables in your CMAKE.
回答2:
I had got a similar error when I hadn't ensured proper scope. It looks like you're importing a lot of headers, just check again.
来源:https://stackoverflow.com/questions/19936166/compiled-so-for-boost-python-cannot-find-module