【发布时间】:2021-02-18 09:24:06
【问题描述】:
我想创建一个使用不支持 python 的 C 库和 ctypes 的模块。
根据this documentation关于创建python的C扩展,我需要提供一个带有签名PyObject* PyInit_modulename(void)的模块初始化函数。与使用我已经拥有的 ctypes 的包装器相比,这看起来很复杂。
到目前为止,我在 unix 上测试了使用 setpuptools 构建扩展,并且它有效。它既简单又方便。但它在 Windows 上不起作用。我使用cibuildwheel 和 github 操作为包括 Windows 在内的所有操作系统构建轮子。 Windows上编译失败,因为找不到函数PyInit_ext。
因此,我需要将我的代码编译为纯 DLL(Windows 共享库)。然后我可以使用ctypes 加载库。这可以通过cibuildwheel 使用的setuptools 来完成吗?
我该怎么做?
这是我的setup.cfg 文件:
[metadata]
name = hello_chmike
version = 0.0.0
url = https://github.com/chmike/hello
maintainer = Christophe Meessen
maintainer_email = christophe@meessen.net
description = Simple python module with external C library
long_description = file: README.md
long_description_content_type = text/markdown
keywords = Example
license = BSD 3-Clause License
license_file = LICENSE.txt
classifiers =
License :: OSI Approved :: BSD License
Programming Language :: Python :: 3
Operating System :: OS Independent
Topic :: Utilities
[options]
packages = hello
python_requires = >=3.6
这是我目前拥有的setup.py 文件,但它使用扩展名并不好:
from setuptools import setup, Extension
setup(
ext_modules=[Extension('hello.ext',
['src/hello.c'],
depends=['src/hello.h'],
include_dirs=['src'],
)],
)
文件hello.c的内容如下:
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS 1
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// hello return a heap allocated string containing the name appended
// to "hello " and followed by "!".
char *hello(char *name) {
char *buf = malloc(7+strlen(name));
sprintf(buf, "hello %s!", name);
return buf;
}
【问题讨论】:
-
如果你不需要在那个函数中做任何事情,只提供一个空函数?我不太了解这件事,但您似乎没有提供。
-
@user202729 确实如此。我没有提供一个。如果我提供一个虚拟的必需功能,它会起作用吗?那个接缝就像一个黑客,但可以解决我的问题。我会试试的。
-
(另一方面,为什么它甚至可以在 UNIX 上编译?)
-
@user202729 根据另一个论坛上的this answer,这是因为在 unix 和 macOS 上,符号是隐式导出的。因此没有编译错误。在 Windows 上,必须显式导出符号,并在编译时检测到丢失的符号。我可以将该符号定义为一个函数,它可以工作。这个函数应该有什么签名?
-
我确实说过我不太了解这件事。阅读文档。
标签: python python-3.x python-extensions