最近,我正尝试从python2转换为python3,在我的代码中,有一些有关读取具有硬件形式的数据的工作,这些硬件具有.py接口文件,称为外部.dll库。数据由.dll和python例程之间的内存共享,具体而言,ctypes.creat_string_buffer()和ctypes.addressof()在python2.7 env下正常运行,但在python3.6下却给出了意外结果,原因似乎是是ctypes.addressof()给出了巨大的地址差值,我想知道是什么原因?
'''''python2.7输出的addressof()
(base) C:\Users\Administrator>python
Python 2.7.15 |Anaconda, Inc.| (default, May 1 2018, 18:37:09) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from ctypes import *
>>> s = 128
>>> p = create_string_buffer(s)
>>> print(addressof(p))
50341488
>>> hex(addressof(p))
'0x3002670L'
'''
'''''python3.6 addressof()的输出
(base) C:\Users\Administrator>conda activate py36
(py36) C:\Users\Administrator>python
Python 3.6.8 |Anaconda, Inc.| (default, Feb 21 2019, 18:30:04) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from ctypes import *
>>> s = 128
>>> p = create_string_buffer(s)
>>> print(addressof(p))
>>> 2241150277680
>>> hex(addressof(p))
>>> '0x209cef75830'
'''
在我看来,python2和python3下的addressof()函数的输出应该是近似的,但实际上不是。有些人可以帮助我指出例程或我有什么毛病! >
答案 0 :(得分:0)
[Python 3.Docs]: ctypes - A foreign function library for Python。
ctypes.addressof
与这些值无关,它只是报告 ctypes 对象的基础 C 缓冲区的地址。>
关于:
ctypes.create_string_buffer
(返回一个ctypes.c_char
数组)输出:
[cfati@CFATI-5510-0:C:\WINDOWS\system32]> sopr.bat *** Set shorter prompt to better fit when pasted in StackOverflow (or other) pages *** [prompt]> [prompt]> set _PYTHON2="e:\Work\Dev\VEnvs\py_064_02.07.15_test0\Scripts\python.exe" [prompt]> set _PYTHON3="e:\Work\Dev\VEnvs\py_064_03.07.03_test0\Scripts\python.exe" [prompt]> rem PYTHON 3 - CTYPES [prompt]> %_PYTHON3% -c "from ctypes import *; print(hex(addressof(create_string_buffer(128))))" 0x25652521230 [prompt]> %_PYTHON3% -c "from ctypes import *; print(hex(addressof(create_string_buffer(128))))" 0x25c61371230 [prompt]> %_PYTHON3% -c "from ctypes import *; print(hex(addressof(create_string_buffer(128))))" 0x20a3dfd1230 [prompt]> rem PYTHON 2 - CTYPES [prompt]> %_PYTHON2% -c "from ctypes import *; print(hex(addressof(create_string_buffer(128))))" 0x2f5f3b0L [prompt]> %_PYTHON2% -c "from ctypes import *; print(hex(addressof(create_string_buffer(128))))" 0x262f3b0L [prompt]> %_PYTHON2% -c "from ctypes import *; print(hex(addressof(create_string_buffer(128))))" 0x313f3b0L [prompt]> [prompt]> rem PYTHON 3 - REGULAR [prompt]> %_PYTHON3% -c "print(hex(id(1234567)))" 0x1df0d6af5b0 [prompt]> %_PYTHON3% -c "print(hex(id(1234567)))" 0x14f39e7f5b0 [prompt]> %_PYTHON3% -c "print(hex(id(1234567)))" 0x1f61453f5b0 [prompt]> rem PYTHON 2 - REGULAR [prompt]> %_PYTHON2% -c "print(hex(id(1234567)))" 0x2a2ca90L [prompt]> %_PYTHON2% -c "print(hex(id(1234567)))" 0x325c6a0L [prompt]> %_PYTHON2% -c "print(hex(id(1234567)))" 0x28bbec0L
如图所示,内存地址模式与 ctypes 对象无关,但与所有对象有关(并且地址每次都不同)。
请注意,依靠指向由 malloc (或朋友)分配的某些内存的地址等于(或接近)某个值的事实是一个坏主意。 依赖于这种假设的代码很糟糕(可能会说这等同于未定义行为)。