I am trying to wrap a c++ library with cython. The library was compiled with Visual studio 2008, similar to my python. I use python 2.7.9 on Windows 7, 64 bit with cython 0.22.
My problem is that I always get a few
LNK2019: unresolved external symbol "...
errors.
As an illustration I used the rectangle example. I first create a testLib.lib from the Rectangle.h and the rectangle.cpp with visual studio, and then try to wrap that with cython. Here are all the files.
Rectangle.h
namespace shapes {
class Rectangle {
public:
int x0, y0, x1, y1;
Rectangle(int x0, int y0, int x1, int y1);
~Rectangle();
int getLength();
};
}
rectangle.cpp
#include "Rectangle.h"
using namespace shapes;
Rectangle::Rectangle(int X0, int Y0, int X1, int Y1)
{
x0 = X0;
y0 = Y0;
x1 = X1;
y1 = Y1;
}
Rectangle::~Rectangle()
{
}
int Rectangle::getLength()
{
return (x1 - x0);
}
I compile the above two files with Visual studo 2008 to testLib.lib. To wrap this testLib I use the following files:
pyRectangle.pyx
cdef extern from "Rectangle.h" namespace "shapes":
cdef cppclass Rectangle:
Rectangle(int, int, int, int)
int x0, y0, x1, y1
int getLength()
cdef class PyRectangle:
cdef Rectangle *thisptr # hold a C++ instance which we're wrapping
def __cinit__(self, int x0, int y0, int x1, int y1):
self.thisptr = new Rectangle(x0, y0, x1, y1)
def __dealloc__(self):
del self.thisptr
def getLength(self):
return self.thisptr.getLength()
setup.py
try:
from setuptools import setup
from setuptools import Extension
except ImportError:
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
setup(
name = 'test',
ext_modules=[Extension("rectangle",
sources = ["pyRectangle.pyx"],
include_dirs=["G:/path/to/cythonTest"],
libraries = ["testLib"],
library_dirs = ["G:/path/to/cythonTest/testLib/Release"],
language="c++",)],
cmdclass = {'build_ext': build_ext},
)
Now I run
python setup.py build_ext --inplace
and get the following errors
pyRectangle.obj : warning LNK4197: export 'initrectangle' specified multiple times; using first specification
Creating library build\temp.win-amd64-2.7\Release\rectangle.lib and object build\temp.win-amd64-2.7\Release\rectangle.exp
pyRectangle.obj : error LNK2019: unresolved external symbol "public: cdecl shapes::Rectangle::Rectangle(int,int,int,int)" (??0Rectangle@shapes@@QEAA@HHHH@Z) referenced in function "int __cdecl __pyx_pf_9rectangle_11PyRectangle___cinit(struct pyx_obj_9rectangle_PyRectangle *,int,int,int,int)" (?__pyx_pf_9rectangle_11PyRectangle___cinit@@YAHPEAU__pyx_obj_9rectangle_PyRectangle@@HHHH@Z)
pyRectangle.obj : error LNK2019: unresolved external symbol "public: cdecl shapes::Rectangle::~Rectangle(void)" (??1Rectangle@shapes@@QEAA@XZ) referenced in function "void __cdecl __pyx_pf_9rectangle_11PyRectangle_2__dealloc(struct pyx_obj_9rectangle_PyRectangle *)" (?__pyx_pf_9rectangle_11PyRectangle_2__dealloc@@YAXPEAU__pyx_obj_9rectangle_PyRectangle@@@Z)
pyRectangle.obj : error LNK2019: unresolved external symbol "public: int __cdecl shapes::Rectangle::getLength(void)" (?getLength@Rectangle@shapes@@QEAAHXZ) referenced in function "struct _object * __cdecl __pyx_pf_9rectangle_11PyRectangle_4getLength(struct __pyx_obj_9rectangle_PyRectangle *)" (?__pyx_pf_9rectangle_11PyRectangle_4getLength@@YAPEAU_object@@PEAU__pyx_obj_9rectangle_PyRectangle@@@Z)
I think my problem is similar to the ticket http://trac.cython.org/ticket/106, but that was marked solved for cython version 0.14, so should actually not be a problem anymore.
If I do not make a library first, but use the cpp file itself in cython, I have no issues, but in the real world with larger projects I want to simply wrap the library.
Any ideas what can be wrong?