Wrap C++ lib with Cython

前端 未结 3 874
没有蜡笔的小新
没有蜡笔的小新 2020-12-23 12:37

I\'m new to Cython and I\'m trying to use Cython to wrap a C/C++ static library. I made a simple example as follow.

Test.h:

#ifndef          


        
相关标签:
3条回答
  • 2020-12-23 12:54

    Your Test.pyx file isn't doing what you expect. The print add(2,3) line will not call the add() C++ function; you have to explicitly create a wrapper function to do that. Cython doesn't create wrappers for you automatically.

    Something like this is probably what you want:

    cdef extern from "test.h":
            int _add "add"(int a,int b)
            int _multiply "multiply"(int a,int b)
    
    def add(a, b):
        return _add(a, b)
    
    def multiply(a, b):
        return _multiply(a, b)
    
    print add(2, 3)
    

    You can look at Cython's documentation for more details.

    0 讨论(0)
  • 2020-12-23 13:06

    I think you can fix this specific problem by specifying the right library_dirs (where you actually put libtest.a -- apparently it's not getting found), but I think then you'll have another problem -- your entry points are not properly declared as extern "C", so the function's names will have been "mangled" by the C++ compiler (look at the names exported from your libtest.a and you'll see!), so any other language except C++ (including C, Cython, etc) will have problems getting at them. The fix is to declare them as extern "C".

    0 讨论(0)
  • 2020-12-23 13:12

    If your C++ code is only used by the wrapper, another option is to let the setup compile your .cpp file, like this:

    from distutils.core import setup
    from distutils.extension import Extension
    from Cython.Distutils import build_ext
    
    ext_modules = [Extension("test",
                         ["test.pyx", "test.cpp"],
                         language='c++',
                         )]
    
    setup(
      name = 'test',
      cmdclass = {'build_ext': build_ext},
      ext_modules = ext_modules
    )
    

    For linking to a static library you have to use the extra_objects argument in your Extension:

    from distutils.core import setup
    from distutils.extension import Extension
    from Cython.Distutils import build_ext
    
    ext_modules = [Extension("test",
                         ["test.pyx"],
                         language='c++',
                         extra_objects=["libtest.a"],
                         )]
    
    setup(
      name = 'test',
      cmdclass = {'build_ext': build_ext},
      ext_modules = ext_modules
    )
    
    0 讨论(0)
提交回复
热议问题