Как вручную установить указатель c_char_p ctypes IronPython на абсолютный адрес? - PullRequest
0 голосов
/ 12 марта 2019

Мне нужно установить адрес, на который указывает символьный указатель, как абсолютное значение.

Во многих реализациях 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.

Что я могу сделать, чтобы установить c_char_p в абсолютный адрес в IronPython?

Фон для моеговопрос:

Я разработал DLL, написанную на Delphi.Назначение библиотеки DLL - иметь внешний интерфейс к приложению Delphi.Я могу успешно управлять приложением через DLL на C и C ++.Клиенты запросили более удобное решение -> они хотят управлять приложением с помощью Python.Я разработал пакет Python, который на самом деле намного проще в использовании.Все функции DLL должны вызываться с указателем на структуру того же типа, которая представляет устройство.Первая функция, которую нужно вызвать, - это функция Init библиотеки DLL, которая инициализирует структуру со значениями по умолчанию.К сожалению, в конструкции структуры отсутствует важный элемент - настройка параметров RS232, поскольку поддержка устройств RS232 не планировалась в первой версии DLL.Чтобы по-прежнему обеспечивать поддержку RS232, библиотека DLL была изменена для использования абсолютного адреса существующего символа * в структуре устройства в качестве сигнала.Если этот символ * имеет абсолютный адрес 0xCAFEBABE, DLL анализирует строку конфигурации, которая была помещена в другой символ * структуры.Это уродливое решение работает очень хорошо, и атрибуты структуры не должны были быть изменены.Все отлично работает при управлении DLL / приложением с помощью CPyhton 2.x, CPython 3.x, PyPy & ActivePython.К сожалению, IronPython сообщает об ошибке при попытке установить указатель на абсолютный адрес.

1 Ответ

0 голосов
/ 12 марта 2019

Очевидно, IPython является более строгим, когда речь идет об адресах, и преобразования должны выполняться вручную. Это можно сделать с помощью [Python 2]: ctypes. cast ( obj, тип ) .

code.py

#!/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 - получить действительный адрес памяти ( buf_addr ), который указывает на char* (как 0xCafeBabe *) 1036 * не имеет смысла в моем Python процессе)
  • cp1 (возьмите их в обратном порядке) - это проблема: попытка создать ctypes.c_char_p из адреса памяти (в соответствии с последним редактированием вопроса: оно заполнено char* некоторые подпрограммы в .dll (которые должны быть загружены в текущем процессе)
    • Это работает (в зависимости от вопроса) в CPython , но вызывает TypeError в IPython
  • cp0 является решением проблемы: попытка создать ctypes.c_char_p из того же адреса памяти
    • Это работает в CPython и IPython
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...