我需要将字符指针指向的地址设置为绝对值。
在许多Python实现中(CPyhton 2.x,CPython 3.x,PyPy和ActivePython,...),这可以使用以下方法完成:
>>> c_char_p(0xcafebabe)
c_char_p(3405691582)
>>>
在IronPython中:
>>> c_char_p(0xcafebabe)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: expected char pointer, got long
>>>
IronPython不会尝试设置指针的地址,而是将参数视为内容,然后返回类型冲突。但是,上面提到的其他Python发行版的功能不适用于IronPython。
如何在IronPython中将c_char_p
设置为绝对地址?
我的问题的背景:
我开发了一个用Delphi编写的DLL。 DLL的目的是为Delphi应用程序提供外部接口。我可以通过C和C ++中的DLL成功控制应用程序。客户要求提供更方便的解决方案 - >他们希望使用Python控制应用程序。我开发了一个实际上更容易使用的Python包。必须使用指向表示设备的相同类型结构的指针来调用所有DLL函数。第一个调用的函数是DLL的Init函数,它使用默认值初始化结构。不幸的是,结构的设计缺少一个重要的项目,即RS232参数的配置,因为在第一版DLL中没有计划支持RS232设备。为了仍然提供RS232支持,DLL已被修改为使用设备结构中现有char *的绝对地址作为信号。如果此char *具有绝对地址0xCAFEBABE,则DLL将解析已放入结构的另一个char *的配置字符串。这个丑陋的解决方案非常有效,并且不必更改结构的属性。使用CPyhton 2.x,CPython 3.x,PyPy和ActivePython控制DLL /应用程序时,一切正常。不幸的是,IronPython在尝试将指针设置为绝对地址时报告错误。
显然,IPython在地址方面更具限制性,转换必须手动执行。这可以通过[Python 2]: ctypes.cast(obj, type)完成。
code.朋友:
#!/usr/bin/env python2
import sys
import ctypes
CharPtr = ctypes.POINTER(ctypes.c_char)
def main():
pchar0 = ctypes.cast(ctypes.c_char_p("Dummy text"), CharPtr) # Create an object that will yield a valid memory address
buf_addr = ctypes.addressof(pchar0.contents) # Raw buffer address
print("Raw buffer address: 0x{:016X}".format(buf_addr))
cp0 = ctypes.cast(buf_addr, ctypes.c_char_p)
print("cp0 ({:s}) value: {:s}\n".format(cp0.__class__.__name__, cp0.value))
cp1 = ctypes.c_char_p(buf_addr)
print("cp1 ({:s}) value: {:s}".format(cp1.__class__.__name__, cp1.value))
if __name__ == "__main__":
print("Python {:s} on {:s}\n".format(sys.version, sys.platform))
main()
输出:
[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q055118583]> "e:\Work\Dev\VEnvs\py_064_02.07.15_test0\Scripts\python.exe" code.py Python 2.7.15 (v2.7.15:ca079a3ea3, Apr 30 2018, 16:30:26) [MSC v.1500 64 bit (AMD64)] on win32 Raw buffer address: 0x00000000036D0690 cp0 (c_char_p) value: Dummy text cp1 (c_char_p) value: Dummy text [cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q055118583]> "c:\Install\IronLanguages\IronPython\02.07.09\net45\ipy.exe" code.py Python 2.7.9 (IronPython 2.7.9 (2.7.9.0) on .NET 4.0.30319.42000 (64-bit)) on cli Raw buffer address: 0x00000209BFF2E860 cp0 (c_char_p) value: Dummy text Traceback (most recent call last): File "code.py", line 24, in <module> File "code.py", line 18, in main TypeError: expected char pointer, got long
笔记:
char*
的有效内存地址(buf_addr)(因为0xCafeBabe在我的Python进程中没有任何意义)ctypes.c_char_p
(根据最新的问题编辑:.dll中的某些例程填充了char*
(必须加载到当前进程))
这在CPython中有效(根据问题),但在IPython中引发了TypeErrorctypes.c_char_p
这适用于CPython和IPython