KCH
KCH

Reputation: 2854

C++ library for python - linking problems

I have written a c++ library, and I'm trying to make python bindings to it with boost::python. This is simplified version of file, where I define them:

#include <boost/python.hpp>
#include <matrix.h>
#include <string>

using namespace boost::python;

class MatrixForPython : public Matrix{
  public:
    MatrixForPython(int size) : Matrix(size) {}

    std::string hello(){
      return "this method works"; 
    }
};

BOOST_PYTHON_MODULE(matrix){
  class_<MatrixForPython>("Matrix", init<int>())
    .def("hello", &MatrixForPython::hello); 
}

Compilation is done by CMake, and here is my CMakeLists.txt:

project(SomeProject)
cmake_minimum_required(VERSION 2.8)

# find and include boost library
find_package(Boost COMPONENTS python REQUIRED)
find_package(PythonLibs REQUIRED)
include_directories(${PYTHON_INCLUDE_PATH})
include_directories(${Boost_INCLUDE_DIR})
include_directories(.)

# compile matrix manipulation library
add_library(matrix SHARED matrix.cpp python_bindings.cpp)
set_target_properties(matrix PROPERTIES PREFIX "")
target_link_libraries(matrix
  ${Boost_LIBRARIES} ${PYTHON_LIBRARIES})

Compilation finishes without errors, but when I try to run simple python script:

import matrix

I get following error

undefined symbol: _ZN6MatrixC2ERKS_

What puzzles me the most is fact, that when I change MatrixForPython not to derive from Matrix everything works as expected. What should I change in order to make it work?

EDIT: matrix.h:

#ifndef MATRIX_H_
#define MATRIX_H_

#include <boost/shared_array.hpp>


class Matrix{
  public:
    // creates size X size matrix
    Matrix(int size);

    // copy constructor
    Matrix(const Matrix& other);

    // standard arithmetic operators
    const Matrix operator * (const Matrix& other) const;
    const Matrix operator + (const Matrix& other) const;
    const Matrix operator - (const Matrix& other) const;

    // element manipulation
    inline void set(int row, int column, double value){
      m_data[row*m_size + column] = value;
    }

    inline double get(int row, int col) const{
      return m_data[row*m_size + col];
    }

    // norms
    double frobeniusNorm() const;
    double scaledFrobeniusNorm() const;
    double firstNorm() const;
    double infNorm() const;

    // entire array manipulation
    void zero();    // sets all elements to be 0
    void one();     // identity matrix
    void hermite(); // hermite matrix


    virtual ~Matrix();


    // less typing
    typedef boost::shared_array<double> MatrixData;

  private:
    int m_size; 
    MatrixData m_data;
};




#endif

Upvotes: 1

Views: 324

Answers (1)

Sam Miller
Sam Miller

Reputation: 24174

undefined symbol: _ZN6MatrixC2ERKS_

This is because you are missing the Matrix::Matrix(const Matrix&) copy constructor in your shared library:

samm@mac ~> echo _ZN6MatrixC2ERKS_ | c++filt 
Matrix::Matrix(Matrix const&)
samm@mac ~> 

Upvotes: 2

Related Questions