OberonCore https://forum.oberoncore.ru/ |
|
Из WinApi.PtrSTR получить массив символов https://forum.oberoncore.ru/viewtopic.php?f=2&t=3190 |
Страница 1 из 1 |
Автор: | Виталий [ Воскресенье, 23 Январь, 2011 16:41 ] |
Заголовок сообщения: | Из WinApi.PtrSTR получить массив символов |
Доброго всем. подскажите как мне из переменной WinApi.PtrSTR получить массив символов. Например чтоб вывести в StdLog текст, который вернула WinAPI функция. |
Автор: | Александр Ильин [ Воскресенье, 23 Январь, 2011 16:52 ] |
Заголовок сообщения: | Re: Из WinApi.PtrSTR получить массив символов |
Виталий писал(а): подскажите как мне из переменной WinApi.PtrSTR получить массив символов. Откуда взялся указатель? Какая функция вернула?Обычно WinApi записывает данные по переданному ей указателю, а не возвращает указатель. Как потом память-то освобождать? |
Автор: | Пётр Кушнир [ Воскресенье, 23 Январь, 2011 16:56 ] |
Заголовок сообщения: | Re: Из WinApi.PtrSTR получить массив символов |
Код: 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 ] |
Заголовок сообщения: | Re: Из WinApi.PtrSTR получить массив символов |
Значит ситуация такая: Изучаю работу ББ с Виндой. Нужно вызывать ДЛЛки написанные в Си. Делфи и т.д. Пока моделирую ситуацию, чтоб понять как и чего. Допустим есть ДЛЛ Код: 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 ] |
Заголовок сообщения: | Re: Из WinApi.PtrSTR получить массив символов |
Смотрите. Pchar - это уже указатель. А у Вас ещё и VAR Pchar. Т.е. Ваша DLL-ная функция возвращает через VAR-параметр указатель на строку. Что и происходит. DLL-ке наплевать на Вами выделенную строку, она просто перетирает параметр указателем на строковую константу Дельфы. И освобождать в конце процедуры ББ Вы уже пытаетесь объект, находящийся в юрисдикции Дельфы. |
Автор: | Виталий [ Понедельник, 24 Январь, 2011 19:38 ] |
Заголовок сообщения: | Re: Из WinApi.PtrSTR получить массив символов |
Хм... Так, ладно. Еще такой вариант Код: 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. Выдает пустую строку, да еще и ББ потом закрывается сам собой. Что в этом случае не так? Вроде как я передаю адрес, по которому зарезервирована память |
Автор: | Geniepro [ Понедельник, 24 Январь, 2011 19:44 ] |
Заголовок сообщения: | Re: Из WinApi.PtrSTR получить массив символов |
С дельфийскими/си++билдеровскими DLL'ками могут быть заморочки -- они нестандартны для винды, информацию о типах содержат, вероятно и свой счётчик ссылок для строк... Как-то тоже возился с ними -- кучу неприятных ощущений испытал. Как тут Илья Ермаков упоминал, неприятности могут быть с теми же строками. |
Автор: | Александр Шостак [ Понедельник, 24 Январь, 2011 20:13 ] |
Заголовок сообщения: | Re: Из WinApi.PtrSTR получить массив символов |
В делфийском модуле должна быть функция, возвращающая pchar. GetMem/FreeMem/NEW/Dispose/String нельзя использовать. RESULT:='1234'; А в Обероне скопируйте переданную строку в массив символов. Если вдруг нужно передать переменную типа string из делфи в оберон, то сделайте её глобальной, возвращайте pchar(s). |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |