OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Пятница, 20 Октябрь, 2017 06:27

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 8 ] 
Автор Сообщение
СообщениеДобавлено: Воскресенье, 23 Январь, 2011 16:41 

Зарегистрирован: Вторник, 10 Ноябрь, 2009 13:15
Сообщения: 58
Доброго всем.
подскажите как мне из переменной WinApi.PtrSTR получить массив символов.
Например чтоб вывести в StdLog текст, который вернула WinAPI функция.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 23 Январь, 2011 16:52 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2284
Откуда: Россия, Санкт-Петербург
Виталий писал(а):
подскажите как мне из переменной WinApi.PtrSTR получить массив символов.
Откуда взялся указатель? Какая функция вернула?
Обычно WinApi записывает данные по переданному ей указателю, а не возвращает указатель. Как потом память-то освобождать?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 23 Январь, 2011 16:56 

Зарегистрирован: Вторник, 29 Август, 2006 12:32
Сообщения: 2395
Откуда: Россия, Ярославль
Код:
TYPE
      Str* = POINTER TO ARRAY [untagged] OF SHORTCHAR;
                            ShortString* = POINTER TO ARRAY OF SHORTCHAR;

   PROCEDURE StrToShortChars* (str: Str): POINTER TO ARRAY OF SHORTCHAR;
      VAR x: ShortString; i: INTEGER;
   BEGIN
      IF (str # NIL) THEN
         NEW(x, LEN(str$)+1);
         FOR i := 0 TO LEN(str$)-1 DO x[i]:=str[i] END;
         RETURN x
      ELSE
         RETURN NIL
      END
   END StrToShortChars;



вместо str скармливаем указатель на строку. для юникода соответсвтенно SHORTCHAR заменить на CHAR


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 23 Январь, 2011 18:11 

Зарегистрирован: Вторник, 10 Ноябрь, 2009 13:15
Сообщения: 58
Значит ситуация такая: Изучаю работу ББ с Виндой. Нужно вызывать ДЛЛки написанные в Си. Делфи и т.д.
Пока моделирую ситуацию, чтоб понять как и чего.

Допустим есть ДЛЛ
Код:
library Project1;

uses    sharemem,
  SysUtils,
  windows,
  Classes;

{$R *.res}
 {$o-}
 procedure ir(var buffer:pchar);
 var s:string;
 begin
  buffer:='1234';
 end;

 exports ir;
begin
end.


Местные подсказали описать модуль импорта, что я и сделал
Код:
MODULE Dll["c:\temp\Project1.dll"];
IMPORT SYSTEM,WinApi;

TYPE   
   PROCEDURE GetBuffer* ["ir"] (VAR lpszAgent:WinApi.PtrSTR);
END Dll.

Тут все нормально.

Теперь юзаю функу ДЛЛки:
Код:
MODULE m;
IMPORT Dll,WinApi,StdLog,ComTools;

PROCEDURE a*;
VAR s:WinApi.PtrSTR;i:INTEGER;
    c:SHORTCHAR;
BEGIN
 StdLog.Clear;
 s:=ComTools.NewEmptySString(6);
 Dll.GetBuffer(s);
 i:=WinApi.GetLastError();
 IF i#0 THEN
     StdLog.String('Ошибка № ');StdLog.Int(i);StdLog.Ln;
 ELSE
  StdLog.Int(LEN(s$));StdLog.Ln;
  FOR i:=0 TO LEN(s$)-1 DO
   c:=s[i];
   StdLog.Char(c);
  END;
 END;
 ComTools.FreeSString(s);
END a;

END m.


Тут тоже норм, спасибо Петру.

Вопрос только в том верно ли я освобождаю память через ComTools.FreeSString(s); ибо на ней выпадает ошибка
Цитата:
illegal memory read

Хотя читается строка из буфера, скормленного ДЛЛке нормально

Некоторые функции примерно такой спецификации
Код:
BOOL ReadFile(
  __in   HANDLE hFile,
  __out  LPVOID lpBuffer,
  __in   DWORD dwNumberOfBytesToRead,
  __out  LPDWORD lpdwNumberOfBytesRead
);

Которые мне придется юзать (Это из самописной ДЛЛ) выдают ошибку
Цитата:
ERROR_INVALID_PARAMETER
87 (0x57)


Поэтому я и хочу научиться на примерах, пока на своих, а потом дальше в лес.

Описываю я ее в модуле так:
Код:
   PROCEDURE Read* ["ReadFile"](
     hFile:WinApi.PtrVoid;OUT lpBuffer:WinApi.PtrSTR;dwNumberOfBytesToRead:LONGINT;OUT lpdwNumberOfBytesRead:LONGINT
   ):BOOLEAN;

И вызываю примерно так как показал в своем примере, передавая туда переменку s:WinApi.PtrSTR, для которой была зарезервирована память через ComTools.NewEmptySString
Вот мне и интересно что это может быть. Где я напортачил...


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 23 Январь, 2011 18:32 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 8821
Откуда: Россия, Орёл
Смотрите. Pchar - это уже указатель. А у Вас ещё и VAR Pchar. Т.е. Ваша DLL-ная функция возвращает через VAR-параметр указатель на строку.

Что и происходит. DLL-ке наплевать на Вами выделенную строку, она просто перетирает параметр указателем на строковую константу Дельфы. И освобождать в конце процедуры ББ Вы уже пытаетесь объект, находящийся в юрисдикции Дельфы.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 24 Январь, 2011 19:38 

Зарегистрирован: Вторник, 10 Ноябрь, 2009 13:15
Сообщения: 58
Хм... Так, ладно. Еще такой вариант
Код:
MODULE Dll["c:\temp\Project1.dll"];
IMPORT SYSTEM,WinApi;

TYPE   
   PROCEDURE GetBuffer* ["ir"] (buf:POINTER TO ARRAY OF SHORTCHAR);
END Dll.

И вызов:
Код:
MODULE m;
IMPORT SYSTEM,Dll,WinApi,StdLog;

PROCEDURE a*;
VAR i:INTEGER;
    buf:POINTER TO ARRAY OF SHORTCHAR;
BEGIN
 StdLog.Clear;
 NEW(buf,10);
 Dll.GetBuffer2(buf);
 i:=WinApi.GetLastError();
 IF i#0 THEN
     StdLog.String('Error ');StdLog.Int(i);StdLog.Ln;
 ELSE
  StdLog.String('String is = ');
  StdLog.String(buf$);
 END;
END a;

END m.


Выдает пустую строку, да еще и ББ потом закрывается сам собой.

Что в этом случае не так? Вроде как я передаю адрес, по которому зарезервирована память


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 24 Январь, 2011 19:44 

Зарегистрирован: Четверг, 12 Июль, 2007 23:18
Сообщения: 1982
Откуда: Узбекистан, Чирчик
С дельфийскими/си++билдеровскими DLL'ками могут быть заморочки -- они нестандартны для винды, информацию о типах содержат, вероятно и свой счётчик ссылок для строк...
Как-то тоже возился с ними -- кучу неприятных ощущений испытал.
Как тут Илья Ермаков упоминал, неприятности могут быть с теми же строками.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 24 Январь, 2011 20:13 

Зарегистрирован: Четверг, 23 Апрель, 2009 18:01
Сообщения: 219
В делфийском модуле должна быть функция, возвращающая pchar.
GetMem/FreeMem/NEW/Dispose/String нельзя использовать.

RESULT:='1234';

А в Обероне скопируйте переданную строку в массив символов.
Если вдруг нужно передать переменную типа string из делфи в оберон, то сделайте её глобальной, возвращайте pchar(s).


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 8 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2017, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB