当前位置: 首页 > 面试题库 >

使用Cython将Python链接到共享库

杜砚
2023-03-14
问题内容

我正在尝试使用集成C使用我的python应用程序编写的第三方库Cython。我已经为测试编写了所有的python代码。我很难找到设置此示例的方法。

我有一个pyd/pyx手动创建的文件。第三方给了我aheader file (*.h)和a shared library (*.so)。据我所知,没有其他依赖项。有人可以提供使用Cython和进行设置的示例disutils吗?

谢谢


问题答案:

当然可以!

(在下文中,我假设你已经知道如何处理cimport之间和交互.pxd.pyx,如果这不是完全的情况下,只问我会开发部分以及)

示例(来自我的C ++项目,但是C项目的工作原理几乎相同):

1. Distutils安装文件:

假设将调用要创建的扩展名,myext并且第3方共享库为libexternlib.so(请注意 lib * 前缀,在此)…

# setup.py file
import sys
import os
import shutil

from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext

# clean previous build
for root, dirs, files in os.walk(".", topdown=False):
    for name in files:
        if (name.startswith("myext") and not(name.endswith(".pyx") or name.endswith(".pxd"))):
            os.remove(os.path.join(root, name))
    for name in dirs:
        if (name == "build"):
            shutil.rmtree(name)

# build "myext.so" python extension to be added to "PYTHONPATH" afterwards...
setup(
    cmdclass = {'build_ext': build_ext},
    ext_modules = [
        Extension("myext", 
                  sources=["myext.pyx",
                           "SomeAdditionalCppClass1.cpp",
                           "SomeAdditionalCppClass2.cpp"
                       ],
                  libraries=["externlib"],          # refers to "libexternlib.so"
                  language="c++",                   # remove this if C and not C++
                  extra_compile_args=["-fopenmp", "-O3"],
                  extra_link_args=["-DSOME_DEFINE_OPT", 
                                   "-L./some/extra/dependency/dir/"]
             )
        ]
)

注意: 您的外部.so文件通过以下libraries选项链接:

libraries=["externlib"]   # Without the 'lib' prefix and the '.so' extension...

注意:该sources选项可用于获取一些其他源文件的编译。

重要提示:(
myext.pxd不要与.pydWindows混淆),并且myext.pyx应该位于同一目录中。在编译时,将首先处理定义文件(如果存在)(更多内容)。

2.然后按以下方式运行:

将目录更改为包含your myext.pxd,yourmyext.pyx和上述setup.py脚本的目录后:

# setup.sh
# Make the "myext" Python Module ("myext.so")
CC="gcc"   \
CXX="g++"   \
CFLAGS="-I./some/path/to/includes/ -I../../../DEPENDENCIES/python2.7/inc -I../../../DEPENDENCIES/gsl-1.15"   \
LDFLAGS="-L./some/path/to/externlib/"   \
    python setup.py build_ext --inplace

哪里:

  • libexternlib.so 假定位于 ./some/path/to/externlib/
  • yourheader.h 假定位于 ./some/path/to/includes/

注意: CFLAGS 也可以使用extra_compile_args选项设置:

extra_compile_args=["-I./some/path/to/includes/", "-fopenmp", "-O3"]

注意: LDFLAGS 也可以使用extra_link_args选项设置:

extra_link_args=["-L./some/path/to/externlib/", "-DSOME_DEFINE_OPT", "-L./some/extra/dependency/dir/"]

distutils完成构建后,您将获得一些新文件,特别是myext.cppmyext.h最重要的是myext.so

3.之后,您就可以开始:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./some/path/to/externlib/
export PYTHONPATH=$PYTHONPATH:./some/path/to/myext/

# Run some script requiring "myext.so"
python somescript.py

新创建的Python扩展名可以通过其名称导入:

# somescript.py
import myext
from myext import PySomeFeature
...

*有关优化*注意事项 :默认情况下-O2,用于编译扩展,但是可以重载(请参见上面-O3指定的设置)。

*有关Cython路径的 *注意事项 :如果将Cython安装在自定义目录中,则可能需要先将其添加到您的环境中:

PYTHONPATH=$PYTHONPATH:../../../DEPENDENCIES/Cython-0.18 export PYTHONPATH;
PATH=$PATH:../../../DEPENDENCIES/Cython-0.18/bin; export PATH;

好吧,希望我能讲到要点…



 类似资料:
  • 我正在尝试链接一个名为libtest lib的预编译共享库文件。所以这是我在CMakeLists的底部所拥有的。txt: 如上所述,我得到以下错误: 如果我注释掉add_library行,我会得到以下结果: 在库中链接时,似乎绝对需要源文件(.c、cpp等)。但我如何在一个。那档案呢?这些文档对target_link_库()做了如下介绍: 被命名的必须是由add_executable()或add_

  • 我试图将我编译的简单共享库(libhello.so)链接到我的本机C++代码中。库libhello.so文件是: 1。Get13.h 2.get13.cpp Android文件是: 1。myapplication/jni/android.mk 问题是,在gradle构建过程中,我在文件native-lib.cpp中得到了这个错误: 我使用android NDK包中包含的make_standalon

  • 问题内容: 我正在尝试建立一个共享库。让我们说libabc.so。它使用另一个.so文件,例如lib123.so(/ usr / local / lib中的一个lib)。现在我在我的应用程序中使用共享的liblibabc.so。说我的应用程序。我想知道我应该如何链接这些二进制文件?我不想直接将我的应用程序与lib123.so链接。my- app应该仅与libabc.so链接。我怎样才能做到这一点?

  • 问题内容: 我希望当用户共享另一个应用程序(例如浏览器)的URL时,我的Android应用程序显示为一个选项。我该如何注册我的应用程序?我如何反应链接共享? 非常感谢。 编辑: 我试过像这样使用IntentFilter,但没有成功: 有任何想法吗? 问题答案: 您至少需要: 在清单中…至少会使其显示在“共享”列表中。 您缺少的最重要的部分是: 要使其实际执行某项操作,您需要一个Activity。

  • 问题内容: 我不想创建一个嵌入python解释器的跨平台程序,并使用MinGW对其进行编译。但是Python Binary发行版不提供供MinGW链接的库(仅适用于Visual C ++),而Python Source包不提供对使用MinGW进行编译的支持。 我尝试在Mingw中链接到,但仍然会产生如下错误: 如何在MinGW中链接Python?我真的不想切换到使用Visual C ++。 问题答

  • #include <hiredis/hiredis.h> int main(void) { char a[1026] = {0}; redisContext *c = NULL; void *reply = NULL; memset(a, 'a', (sizeof(a) - 1)); c = redisConnec