SWIG为Python模块生成两个 Package 层:C Package 器代码和Python Package 器代码。而且,据我所知,两者都不知道Python 3. x(目前是3. 1 - 3. 6)的特定subversion。
但是,在编译代码时,我必须包含特定Python 3.x版本的头文件,其中包含PyConfig.h
中的特定库版本,例如3.4:pragma comment(lib,"python34.lib")
-这会导致Python包必须在运行时找到并加载python34.dll
,而在任何其他版本中加载都将失败。
但是Python 3.x的所有版本都是兼容的,并且只需对生成的.pyd
二进制文件进行简单的编辑--用python36.dll
替换python34.dll
就可以使最终的模块与Python 3.6一起工作。
有没有办法用SWIG创建一个Python 3.x包,它能够搜索并找到系统上安装的任何可用的3.x版本?
2条答案
按热度按时间cl25kdpy1#
您可以“强制”将您的项目链接到
python3.lib
而不是链接到python3X.lib
(其中X
是次要版本)。 Package 器将python3.dll
作为其导入的一部分,并且python3.dll
将转发到python3X.dll
。然而,注意你使用的API必须来自Python 3 API的公共集合(我相信从Python 3.2开始,参见下面的参考),如果你需要使用Python 3.2中不存在的API,但是Python 3.3以后的版本中存在,你的SWIG Package 器仍然会链接到次要库。
例如,如果你正在使用从Python 3.3开始就存在的
PyUnicode_AsUTF8
或PyUnicode_AsUTF8AndSize
,然后你试图编译Python 3.6和Python 3.7的 Package 器,尽管这些API在两个版本中是通用的,但是它们将作为python36.dll
和python37.dll
导入的一部分被包括进来。参考文件:PEP 384
yacmzcpb2#
我还尝试构建一个Python 3通用SWIG库,因为我的库的用户可能安装了不同版本的Python 3,目前我需要为每个版本的Python(3.7、3.8、3.9 ......)构建不同的库,这越来越难以维护,并且会让客户感到困惑。
我尝试过定义Py_LIMITED_API,但不幸的是,看起来SWIG使用了完整API中的函数,例如在classobject. h中找到的PyInstanceMethod_New()。
我能够破解SWIG生成的 *_wrap.c文件,以删除对PyInstanceMethod_New的引用(),同样的编译模块现在看起来确实在Python 3.7和Python 3.11中加载了,但这只是一个非常简单的例子,调用了一个C函数,并且没有类。我担心更复杂的C++类库不会以同样的方式工作。如果有人对如何创建通用的Python 3 SWIG Package 库有更多的最新想法,我将非常感激。