Python, ctypes, библиотеки DLL и эмуляция PCOMM. Как я могу предварительно выделить переменную?

После долгого изучения Python мне наконец удалось сделать несколько прорывов:

Я использую следующий код для подключения к персональному терминалу связи:

from ctypes import *
import sys
PCSHLL32 = windll.PCSHLL32
hllapi = PCSHLL32.hllapi

def connect_pcomm(presentation_space):
    function_number = c_int(1)
    data_string = c_char_p(presentation_space)
    lenght = c_int(4)
    ps_position = c_int(0)
    hllapi(byref(function_number), data_string, byref(lenght), byref(ps_position))

И пока все хорошо. Он подключается к терминалу, и я могу использовать другие функции для отправки ключей на экран, отключения и т. д. и т. д.

Моя проблема связана с функцией 5, как определено в документации IBM:

http://publib.boulder.ibm.com/infocenter/pcomhelp/v5r9/index.jsp?topic=/com.ibm.pcomm.doc/books/html/emulator_programming08.htm

«Функция «Копировать пространство презентации» копирует содержимое пространства презентации, подключенного к хосту, в строку данных, которую вы определяете в прикладной программе EHLLAPI».

Код, который я написал для этого (который не такой уж и особенный):

def copy_presentation_space():
    function_number = c_int(5)
    data_string = c_char_p("")
    lenght = c_int(0)
    ps_position = c_int(0)
    hllapi(byref(function_number), data_string, byref(lenght), byref(ps_position))

Основная проблема заключается в том, что переменная data_string должна быть: «Предварительно выделенная целевая строка размером с пространство для презентации вашего хоста».

Поскольку я точно не знал, что это значит, я просто попытался запустить код. И pythonw.exe разбился. Эпично. Окно терминала тоже начало падать. Ошибок не выдавало, просто говорило, что перестало работать.

Теперь мой главный вопрос: как я могу предварительно выделить строку, как это указано в IBM ref. материал?

Могу ли я просто добавить «print data_string» после копирования экрана, чтобы увидеть информацию, или мне нужно использовать некоторые ctypes, чтобы иметь возможность просматривать скопированную информацию?

РЕДАКТИРОВАТЬ: я забыл упомянуть, что мне не нужно использовать эту функцию, я мог бы просто использовать эту:

Копировать пространство презентации в строку (8)

Я пытался использовать его, но переменная data_string никогда не меняет значение.

EDIT2: следуя предложению Кватфорда, я изменил строку

data_string = c_char_p("")

To

data_string = create_string_buffer(8000)

Теперь функция не будет аварийно завершать работу и возвращает значение 0, означающее, что: «Содержимое основной области презентации было скопировано в прикладную программу. Целевая область презентации была активной, и клавиатура была разблокирована». Но когда я пытаюсь напечатать переменную data_string, я все равно получаю пустой результат.


person Johnny Bigoode    schedule 01.08.2012    source источник


Ответы (1)


Вы можете создать предварительно выделенный строковый буфер, используя ctypes.create_string_buffer.

Однако вам все равно нужно знать, насколько большим будет буфер. Я не знаком с программным обеспечением, которое вы пытаетесь запустить, но, похоже, вам понадобится:

  • Пространство не менее 25 x 80 символов Юникода.
  • Возможно место для расширенных атрибутов для этих символов

Итак, грубо говоря, я бы сказал, что строка должна иметь не менее 25*80*2*2 = 8000 байтов.

Я рекомендую более подробно прочитать документацию, чтобы определить правильное значение, если это не сработает.

person kwatford    schedule 01.08.2012
comment
это имеет смысл. исходный код, который я использовал в Visual Basic, имеет объявление переменной с использованием «string * 8000». Я обновил исходный вопрос, чтобы проверить, можете ли вы помочь со второй возникшей проблемой. Переменная, которая должна содержать информацию о снимке экрана, пуста. На самом деле я получаю информацию: объект ctypes.c_char_Array_8000 по адресу 0x020B0300›, когда печатаю его. Думаю, мне следует прочитать документацию по ctypes, чтобы проверить, что не так. В любом случае спасибо! - person Johnny Bigoode; 01.08.2012
comment
@JohnnyBigoode Этот объект строкового буфера имеет свойства, которые вы можете проверить, чтобы получить фактические данные. Один называется value, а другой raw. Поскольку здесь могут быть данные расширенного атрибута, интерпретация их как строки может работать некорректно, поэтому я бы рекомендовал использовать свойство raw. Затем вы можете извлечь из него атрибуты и символы Юникода (что потребует повторного просмотра документации библиотеки, чтобы определить формат). - person kwatford; 01.08.2012
comment
Я использовал метод «значение», и, кажется, все в порядке. Я изучу «сырое», прежде чем предпринимать определенные действия. - person Johnny Bigoode; 02.08.2012