5

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

8
  • c++filt says _ZTIN5noise6module6ModuleE is mangled for typeinfo for noise::module::Module, I would guess you have a virtual function that is not defined. If you include the Module class definition we can give you a definitive answer. Commented Nov 12, 2013 at 18:47
  • @SamMiller I added code, but I don't have virtual functions inside. Can you help ? Commented Nov 12, 2013 at 19:51
  • 3
    A quick glance at the libnoise library indicates it is not a header only library. Try updating the CMakeLists.txt file to link against the libnoise library. Commented Nov 12, 2013 at 21:46
  • 1
    I'm not so familiar with CMake, but it sounds like @TannerSansbury was suggesting adding noise to the target_link_libraries list in your CMakeLists.txt file. You may need to also add noise and/or noise/src to the include_directories as well. Commented Nov 18, 2013 at 5:36
  • 2
    @TannerSansbury, cm2: What's wrong with you people, please use comments for comments, and answers for answers. Please post your answers as an answer. Commented Jan 1, 2014 at 9:49

2 Answers 2

0

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.