3

在 Python 中,如果旨在使其与 Py3 和 Py2 兼容,那么为 c++ 库编写 Python 包装器的方式有什么不同吗?

或者最初为 Py2 编写的包装器是否应该以与 Py3 相同的方式工作,反之亦然?据我了解,Python 包装器是用 C++ 编写的 .cxx 文件,然后必须对其进行编译。

细节

我问是因为我想安装 Aggdraw(c++ Anti Grain Geometry 绘图库的包装器),它在 Python 2.6-7 中工作,但在 Python 3.4(Windows 7 32 位,通过“PATH=C:/ Python27[或 Python34]”和“python setup.py install”在命令行中)。我希望为 Python 3 重振这个令人惊叹的包装模块,并希望这里的其他人能有兴趣提供帮助。

我可以在 Python 2.6 和 2.7 上毫无问题地编译它,而且我同时拥有 Visual C++ 2008 和 2010,所以这不是编译器问题。问题似乎出在实际的 .cxx 包装代码中。

会不会是 Aggdraw 包装器只考虑了 Python 2x(现在差不多 10 年前)编写了,所以它没有考虑 Python 3x 中可能出现的问题?我最好的猜测是,由于 3.4 版中已弃用和更改的功能,包装器无法将某些 c++ 对象/类型转换为 Python。

我可能愿意通过 .cxx 包装代码来更改必要的部分,如果有人可以帮助我确定故障部分是什么(请参阅下面的命令行错误代码)?如果我们修复了它,那么我将使用指向“恢复的”包装代码的链接来更新这篇文章。

如果 Python 2 和 3 包装器之间不应该有区别,知道为什么我在 Py3 中得到下面的错误代码而不是 Py2 吗?

谢谢!

原始包装代码:点击这里

C:\Users\BIGKIMO\Desktop\aggdraw-master>python setup.py build
=== freetype not available (edit setup.py to enable)
running install
running build
running build_ext
building 'aggdraw' extension
C:\Program Files\Microsoft Visual Studio 10.0\VC\BIN\cl.exe /c /nologo /Ox /MD /
W3 /GS- /DNDEBUG -Iagg2/include -IC:\Python34\include -IC:\Python34\include /Tpa
ggdraw.cxx /Fobuild\temp.win32-3.4\Release\aggdraw.obj
aggdraw.cxx
aggdraw.cxx(124) : error C2440: 'initializing' : cannot convert from 'const char
 [5]' to 'Py_ssize_t'
        There is no context in which this conversion is possible
aggdraw.cxx(126) : error C2440: 'initializing' : cannot convert from 'destructor
' to 'printfunc'
        This conversion requires a reinterpret_cast, a C-style cast or function-
style cast
aggdraw.cxx(128) : error C2440: 'initializing' : cannot convert from 'getattrfun
c' to 'setattrfunc'
        This conversion requires a reinterpret_cast, a C-style cast or function-
style cast
aggdraw.cxx(142) : error C2440: 'initializing' : cannot convert from 'const char
 [4]' to 'Py_ssize_t'
        There is no context in which this conversion is possible
aggdraw.cxx(144) : error C2440: 'initializing' : cannot convert from 'destructor
' to 'printfunc'
        This conversion requires a reinterpret_cast, a C-style cast or function-
style cast
aggdraw.cxx(161) : error C2440: 'initializing' : cannot convert from 'const char
 [6]' to 'Py_ssize_t'
        There is no context in which this conversion is possible
aggdraw.cxx(163) : error C2440: 'initializing' : cannot convert from 'destructor
' to 'printfunc'
        This conversion requires a reinterpret_cast, a C-style cast or function-
style cast
aggdraw.cxx(187) : error C2440: 'initializing' : cannot convert from 'const char
 [5]' to 'Py_ssize_t'
        There is no context in which this conversion is possible
aggdraw.cxx(189) : error C2440: 'initializing' : cannot convert from 'destructor
' to 'printfunc'
        This conversion requires a reinterpret_cast, a C-style cast or function-
style cast
aggdraw.cxx(191) : error C2440: 'initializing' : cannot convert from 'getattrfun
c' to 'setattrfunc'
        This conversion requires a reinterpret_cast, a C-style cast or function-
style cast
aggdraw.cxx(207) : error C2440: 'initializing' : cannot convert from 'const char
 [5]' to 'Py_ssize_t'
        There is no context in which this conversion is possible
aggdraw.cxx(209) : error C2440: 'initializing' : cannot convert from 'destructor
' to 'printfunc'
        This conversion requires a reinterpret_cast, a C-style cast or function-
style cast
aggdraw.cxx(211) : error C2440: 'initializing' : cannot convert from 'getattrfun
c' to 'setattrfunc'
        This conversion requires a reinterpret_cast, a C-style cast or function-
style cast
aggdraw.cxx(488) : error C3861: 'PyString_Check': identifier not found
aggdraw.cxx(489) : error C3861: 'PyString_AS_STRING': identifier not found
aggdraw.cxx(575) : error C3861: 'PyString_Check': identifier not found
aggdraw.cxx(583) : error C3861: 'PyString_AS_STRING': identifier not found
aggdraw.cxx(584) : error C3861: 'PyString_GET_SIZE': identifier not found
aggdraw.cxx(730) : error C3861: 'PyInt_Check': identifier not found
aggdraw.cxx(730) : error C3861: 'PyInt_AS_LONG': identifier not found
aggdraw.cxx(731) : error C3861: 'PyInt_Check': identifier not found
aggdraw.cxx(731) : error C3861: 'PyInt_AS_LONG': identifier not found
aggdraw.cxx(735) : error C3861: 'PyInt_Check': identifier not found
aggdraw.cxx(735) : error C3861: 'PyInt_AS_LONG': identifier not found
aggdraw.cxx(736) : error C3861: 'PyInt_Check': identifier not found
aggdraw.cxx(736) : error C3861: 'PyInt_AS_LONG': identifier not found
aggdraw.cxx(742) : error C3861: 'PyInt_Check': identifier not found
aggdraw.cxx(742) : error C3861: 'PyInt_AS_LONG': identifier not found
aggdraw.cxx(745) : error C3861: 'PyInt_Check': identifier not found
aggdraw.cxx(745) : error C3861: 'PyInt_AS_LONG': identifier not found
aggdraw.cxx(759) : error C3861: 'PyInt_Check': identifier not found
aggdraw.cxx(760) : error C3861: 'PyInt_AsLong': identifier not found
aggdraw.cxx(763) : error C3861: 'PyString_Check': identifier not found
aggdraw.cxx(765) : error C3861: 'PyString_AS_STRING': identifier not found
aggdraw.cxx(788) : error C3861: 'PyString_Check': identifier not found
aggdraw.cxx(789) : error C3861: 'PyString_AS_STRING': identifier not found
aggdraw.cxx(1157) : error C3861: 'PyString_FromStringAndSize': identifier not fo
und
aggdraw.cxx(1289) : error C3861: 'PyString_FromString': identifier not found
aggdraw.cxx(1294) : error C3861: 'Py_FindMethod': identifier not found
aggdraw.cxx(1482) : error C3861: 'Py_FindMethod': identifier not found
aggdraw.cxx(1890) : error C3861: 'Py_FindMethod': identifier not found
aggdraw.cxx(1910) : error C3646: 'initaggdraw' : unknown override specifier
aggdraw.cxx(1911) : error C2091: function returns function
aggdraw.cxx(1911) : error C4430: missing type specifier - int assumed. Note: C++
 does not support default-int
aggdraw.cxx(1912) : error C2039: 'ob_type' : is not a member of '_typeobject'
        c:\python34\include\object.h(334) : see declaration of '_typeobject'
aggdraw.cxx(1912) : error C2039: 'ob_type' : is not a member of '_typeobject'
        c:\python34\include\object.h(334) : see declaration of '_typeobject'
aggdraw.cxx(1913) : error C2039: 'ob_type' : is not a member of '_typeobject'
        c:\python34\include\object.h(334) : see declaration of '_typeobject'
aggdraw.cxx(1913) : error C2039: 'ob_type' : is not a member of '_typeobject'
        c:\python34\include\object.h(334) : see declaration of '_typeobject'
aggdraw.cxx(1913) : error C2039: 'ob_type' : is not a member of '_typeobject'
        c:\python34\include\object.h(334) : see declaration of '_typeobject'
aggdraw.cxx(1915) : error C3861: 'Py_InitModule': identifier not found
aggdraw.cxx(1940) : warning C4508: 'DL_EXPORT' : function should return a value;
 'void' return type assumed
4

2 回答 2

3

Python FFI 库 (ctype) 在每个 python 版本之间都有变化。您可以通过更改列表查看到底有什么不同以及为什么它不起作用。

例如,两个 Python 版本之间的 ssizet 和字符串是不同的。

https://docs.python.org/3/whatsnew/3.2.html#ctypes Python 2 和 3 之间 ctypes 的差异

于 2014-09-24T23:28:08.063 回答
1

为了扩展前面的答案,有许多函数在 Py2.7 中作用于字符串,现在在 Py3 中作用于字节或 unicode。类似地,现在提到的 int 可能是指 long。作为此处导致问题的一个示例,PyString_Check 已被 pyBytes_Check 弃用。阅读以下内容了解更多详情:

https://docs.python.org/3/howto/cporting.html?highlight=pystring

于 2016-05-08T23:02:44.420 回答