c++ class convect to cython occur an error

30 views
Skip to first unread message

kai jay

unread,
Jun 15, 2016, 4:01:02 PM6/15/16
to cython-users
The Cython code as below

# distutils: language = c++
# distutils: sources = cppcode.cpp 
from libcpp.string cimport string

cdef extern from "cppcode.h" namespace "mynamespace":
cppclass LinkedList[T]:
    LinkedList ()
    void append (T)
    int getLength ()
    void remove (int)
    void printList ()
    int tes ()

cdef class linklist:

    cdef LinkedList[string] * listt

def __cinit__(self):
    self.listt = new LinkedList[string]()
    if self.listt == NULL:
        raise MemoryError()

def __dealloc__(self):
    if self.listt != NULL:
        del self.listt

cpdef int tests(self):
    return self.listt.tes()

cpdef void appendlist(self,value):
    return self.listt.append(value)
The C++ code as below
using namespace std;

template <class T>
void mynamespace::LinkedList<T>::append (T value)
{
   if (head == NULL)
     {
       head = new ListNode (value);
       tail = head;
     }
   else
     {
       tail->next = new ListNode (value);
       tail = tail->next;
     }
   length++;
}

template <class T>
void mynamespace::LinkedList<T>::printList (void)
{
  if (head != NULL)
    {
      ListNode * it = head;
      while (it != NULL)
    {
      cout << it->value << endl;
      it = it->next;
    }
    }
}

template <class T>
int mynamespace::LinkedList<T>::getLength (void)
{
  return length;
}

template <class T>
int mynamespace::LinkedList<T>::tes ()
{
  return 10;
}

template <class T>
void mynamespace::LinkedList<T>::remove (int idx)
{
  if (head != NULL)
    {
      // invalid element to remove...
      if (idx < 0 || idx > length)
    return;

      if (idx == 0)
    {
      ListNode * tmp = head;
      head = tmp->next;
      delete tmp;
      length--;
    }
      else
    {
      ListNode * it = head;
      ListNode * parent = it;

      int i;
      bool found = false;

      for (i = 0; i < length; ++i)
      {
          if (i == idx)
        {
          found = true;
          break;
        }
          parent = it;
          it = parent->next;
      }

      if (found)
      {
          parent->next = it->next;
          delete it;
          length--;
      }
    }
     }
}

I have try to create a class by cython , but when I compile it to .pyd file have an error occur. But when I delete the function (test) and (appendlist) it can pass the compile.

The error message as below:

cpycode.obj : warning LNK4197: export 'PyInit_cpycode' specified multiple times; using first specification
Creating library build\temp.win-amd64-3.5\Release\cpycode.cp35-win_amd64.lib and object build\temp.win-amd64-3.5\Release\cpycode.cp35-win_amd64.exp
cpycode.obj : error LNK2001: unresolved external symbol "public: int __cdecl mynamespace::LinkedList<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >::tes(void)" (?tes@?$LinkedList@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@mynamespace@@QEAAHXZ)
C:\pptemplates\cpycode.cp35-win_amd64.pyd : fatal error LNK1120: 1 unresolved externals
error: command 'C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\BIN\\amd64\\link.exe' failed with exit status 1120

Tom Swirly

unread,
Jun 17, 2016, 10:24:02 AM6/17/16
to cython-users
You do seem to have a definition for that method!  But, OK, I do finally have a theory.  :-)

Looks like we're missing a bunch of code - the code that declares mynamespace::LinkedList<T>

(What you have is the template definitions of mynamespace::LinkedList<T>!)

So my theory is that "cppcode.h" contains the declaration of this class, and you aren't including the definitions, which might be in "cppcode_inl.h" or even in a .cpp.
Reply all
Reply to author
Forward
0 new messages