Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Cython C+中未定义的符号+;包装纸_Python_C++_Cython_Cythonize - Fatal编程技术网

Python Cython C+中未定义的符号+;包装纸

Python Cython C+中未定义的符号+;包装纸,python,c++,cython,cythonize,Python,C++,Cython,Cythonize,我有一个正在工作的cpp项目,它可以通过cmake很好地构建。现在我需要为同样的代码创建一个Python包装器。所以我选择了cython来弥补C++和Python之间的差距 我没有在pyx文件中编写CMakeLists.txt逻辑,而是尝试使用cmake本身编译库,然后用Cython包装器将其包装起来。以下是setup.py文件: import os import sys from distutils.core import setup from distutils.extension imp

我有一个正在工作的
cpp
项目,它可以通过
cmake
很好地构建。现在我需要为同样的代码创建一个Python包装器。所以我选择了
cython
来弥补
C++
Python
之间的差距

我没有在
pyx
文件中编写
CMakeLists.txt
逻辑,而是尝试使用
cmake
本身编译库,然后用Cython包装器将其包装起来。以下是
setup.py
文件:

import os
import sys

from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize


try:
    build_dir = os.path.join(os.getcwd(), "build")
    print("building bobcore.a")
    if not os.path.exists(build_dir):
        os.makedirs(build_dir)
    if not os.path.exists(build_dir):
        raise Exception("Not able to create `build` directory")

    os.chdir(build_dir)
    assert os.system("cmake ..") == 0
    assert os.system("make -j4") == 0
    os.chdir(os.path.abspath(os.path.join(os.getcwd(), os.pardir)))
except:
    if not os.path.exists("build/bobcli"):
        print("Error building external library, please create libsample.a manually.")
        sys.exit(1)

_ext_modules = cythonize([
    Extension("call_core",
              sources=["call_core.pyx"],
              language="c++",
              extra_compile_args=["-std=c++11", "-lpthread", "-lz", "-ldl"],
              extra_link_args=["-std=c++11"],
              include_dirs=[os.path.join(os.getcwd(), "src")],  # path to .h file(s)
              library_dirs=[os.path.join(os.getcwd(), "build")],  # path to .a or .so file(s)
              libraries=["bobcli"] # name of pre-built .so file.
              )
])

setup(
    name='Demos',
    ext_modules=_ext_modules,
)
cdef extern from "src/api/Api.h" namespace "cli":
    cdef cppclass Api:
        int getVal()


cdef Api *api = new Api()

def getHelp():
    return api.getVal()

del api
以下是
call_core.pyx
文件:

import os
import sys

from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize


try:
    build_dir = os.path.join(os.getcwd(), "build")
    print("building bobcore.a")
    if not os.path.exists(build_dir):
        os.makedirs(build_dir)
    if not os.path.exists(build_dir):
        raise Exception("Not able to create `build` directory")

    os.chdir(build_dir)
    assert os.system("cmake ..") == 0
    assert os.system("make -j4") == 0
    os.chdir(os.path.abspath(os.path.join(os.getcwd(), os.pardir)))
except:
    if not os.path.exists("build/bobcli"):
        print("Error building external library, please create libsample.a manually.")
        sys.exit(1)

_ext_modules = cythonize([
    Extension("call_core",
              sources=["call_core.pyx"],
              language="c++",
              extra_compile_args=["-std=c++11", "-lpthread", "-lz", "-ldl"],
              extra_link_args=["-std=c++11"],
              include_dirs=[os.path.join(os.getcwd(), "src")],  # path to .h file(s)
              library_dirs=[os.path.join(os.getcwd(), "build")],  # path to .a or .so file(s)
              libraries=["bobcli"] # name of pre-built .so file.
              )
])

setup(
    name='Demos',
    ext_modules=_ext_modules,
)
cdef extern from "src/api/Api.h" namespace "cli":
    cdef cppclass Api:
        int getVal()


cdef Api *api = new Api()

def getHelp():
    return api.getVal()

del api
现在,如果我在头文件本身中实现
getVal()
方法,这个文件就可以正常工作。但是,当我将实现移动到
.cpp
文件时,Cython编译器显示以下错误:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: /usr/local/lib/python2.7/dist-packages/call_core.so: undefined symbol: _ZN3cli9Api6getValEv
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
导入错误:/usr/local/lib/python2.7/dist-packages/call_core.so:未定义的符号:_ZN3cli9Api6getValEv

注意:上面的代码片段非常适合在
.h
文件中实现的函数。

我想这不是编译器,而是加载程序。你的so库需要在加载程序可以找到它的地方。这个答案解释了你的问题并展示了一些可能的解决方案:这是一个非常详细的答案,我将很快研究它并更新问题。