如何手动将IronPython ctypes c_char_p指针设置为绝对地址?

问题描述 投票:0回答:1

我需要将字符指针指向的地址设置为绝对值。

在许多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在尝试将指针设置为绝对地址时报告错误。

python pointers ctypes ironpython
1个回答
0
投票

显然,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

笔记:

  • pchar0的目的只是获取一个指向char*的有效内存地址(buf_addr)(因为0xCafeBabe在我的Python进程中没有任何意义)
  • cp1(以相反顺序取出)是问题陈述:尝试从内存地址创建一个ctypes.c_char_p(根据最新的问题编辑:.dll中的某些例程填充了char*(必须加载到当前进程)) 这在CPython中有效(根据问题),但在IPython中引发了TypeError
  • cp0是问题解决方案:尝试从相同的内存地址创建ctypes.c_char_p 这适用于CPython和IPython
© www.soinside.com 2019 - 2024. All rights reserved.