【问题标题】:Create a DLL exposing python code创建一个暴露python代码的DLL
【发布时间】:2013-12-08 21:01:49
【问题描述】:

我可以使用 cython 创建一个以 Python 代码为核心的导出 C 函数的共享库吗?就像用 C 封装 Python 一样??

用于插件。 tk

【问题讨论】:

标签: python c plugins cython


【解决方案1】:

使用 Cython,您可以使用 cdef 关键字(和 public... 重要!),使用 Python 内部代码编写声明为 C 的函数:

yourext.pyx

cdef int public func1(unsigned long l, float f):
    print(f)       # some python code

注意:以下假设我们工作在驱动器 D 的根目录:\

建筑 (setup.py)

from distutils.core import setup
from Cython.Distutils import build_ext
setup(
      cmdclass = {'build_ext': build_ext},
      name = 'My app',
      ext_modules = cythonize("yourext.pyx"),
)

然后运行python setup.py build_ext --inplace

运行setup.py(如果你使用distutils)后,你会得到2个感兴趣的文件:

  • yourext.h
  • yourext.c

查看.c 最终会告诉您func1 是一个C 函数。

剩下的就是这两个文件了。

用于测试的 C 主程序

// test.c
#include "Python.h"
#include "yourext.h"

main()
{
    Py_Initialize(); // start python interpreter
    inityourext();   // run module yourext

    func1(12, 3.0);  // Lets use shared library...

    Py_Finalize();
}

由于我们不单独使用扩展名 (.pyd),我们需要在头文件中做一些小技巧/破解来禁用“DLL 行为”。在“yourext.h”开头添加以下内容:

#undef DL_IMPORT            # Undefines DL_IMPORT macro
#define DL_IMPORT(t) t      # Redefines it to do nothing...

__PYX_EXTERN_C DL_IMPORT(int) func1(unsigned long, float);

将“yourext”编译为共享库

gcc -shared yourext.c -IC:\Python27\include -LC:\Python27\libs -lpython27 -o libyourext.dll

然后编译我们的测试程序(链接到DLL)

gcc test.c -IC:\Python27\include -LC:\Python27\libs -LD:\ -lpython27 -lyourext -o test.exe

最后,运行程序

$ test
3.0

这并不明显,还有很多其他方法可以实现相同的目标,但这是可行的(查看boost::python,...,其他解决方案可能更适合您的需求)。

我希望这能回答你的问题,或者至少给你一个想法......

【讨论】:

  • 非常感谢您提供详尽的答案。我会通过它。看起来不错
  • 好的,请随时通知我们(即使您的最终解决方案不是 Cython,我也很感兴趣!),如果您使用 Cython 获得有趣的结果,请不要犹豫answer your own question...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多