OberonCore https://forum.oberoncore.ru/ |
|
Проблема: Delphi <--> CP https://forum.oberoncore.ru/viewtopic.php?f=5&t=5520 |
Страница 1 из 2 |
Автор: | prospero78 [ Среда, 14 Октябрь, 2015 20:37 ] |
Заголовок сообщения: | Проблема: Delphi <--> CP |
Есть уже готовый сервер телемеханики у нас на подстанции. Написан на Delphi 6. К нему есть библиотека в виде DLL и файл с примером её использования. Я на КП решил сделать допил сервера -- он не может делать нужные мне вещи. В DLL есть функции которые отрабатывают нормально: Код: function tmInit(ServerName, LocalName: PChar):SmallInt .... stdcall...'_tmInit@8' function tmClose():SmallInt.... stdcall.... '_tmClose@0' А вот при попытке передать структуру по ссылке вылетает исключение: Код: function tmGetAnalog(cannel, remote_technic_unit, point: SmallInt; pStatus:pTs):SmallInt....stdcall....'_tmGetAnalog@12' Судя по кратности байтов в передаче -- все параметры передаются по 4 байта (32 бита). Тип описанный в исходнике: Код: type TStatus = record Status: SmallInt; Field: DWORD; end; pTs = @TStatus (* возможно тут ошибся, но точно указатель на record *) Как эту структуру описал я в КП: Код: TYPE TStatus* = RECORD Status*: SHORTINT; Field* : CHAR; end; pTs = POINTER TO TStatus И, короче, понятно. не катит. Коллеги, подскажите, что я делаю не так? Не подскажете -- пеняйте на себя. Буду плюшку рисовать на Delphi))))) (* жуткий завал на работе, пришлось свой почин по учебнику пока приостановить *) ADD. Есть ли у кого-то на крайний случай опыт стыковки DLL (Delphi 6) + FreePascal\Lazarus. Нет желания проприетарщину гонять. |
Автор: | Илья Ермаков [ Среда, 14 Октябрь, 2015 20:54 ] |
Заголовок сообщения: | Re: Проблема: Delphi <--> CP |
Почитайте в доке ББ раздел Платформенно-зависимые особенности. Нужно RECORD, соответствующий чужим структурам, объявлять как [untagged]. |
Автор: | Иван Кузьмицкий [ Среда, 14 Октябрь, 2015 20:58 ] |
Заголовок сообщения: | Re: Проблема: Delphi <--> CP |
Надо делать через [untagged] RECORD, на форуме много было обсуждений этого. |
Автор: | prospero78 [ Среда, 14 Октябрь, 2015 21:13 ] |
Заголовок сообщения: | Re: Проблема: Delphi <--> CP |
Я уже пробовал untagged. Не помогло. Сейчас, пока ел, подумал, почему я DWORD и CHAR приравнял? Хорошо бы где-то информации накопать по размерам типов в Delphi) |
Автор: | Илья Ермаков [ Среда, 14 Октябрь, 2015 21:23 ] |
Заголовок сообщения: | Re: Проблема: Delphi <--> CP |
word - 16 бит. DWORD, соответственно (он вообще WinApi-вский, по-моему) - 32. Как и Cardinal. Т.е. неправильно приравняли. Shortint сколько бит в дельфе? 16? |
Автор: | prospero78 [ Среда, 14 Октябрь, 2015 21:28 ] |
Заголовок сообщения: | Re: Проблема: Delphi <--> CP |
SmallInt -- да. 16 бит. -32000....+32000. |
Автор: | Роман М. [ Четверг, 15 Октябрь, 2015 01:58 ] |
Заголовок сообщения: | Re: Проблема: Delphi <--> CP |
Для примера можно посмотреть исходник модуля WinApi (прокрутив до следующей секции TYPE). Возможно вместо RECORD [untagged] нужно выставить RECORD [noalign]. Код: IMPORT SYSTEM; TYPE PChar = POINTER TO ARRAY [untagged] OF SHORTCHAR; DWORD = INTEGER; SmallInt = SHORTINT; TStatus* = RECORD [noalign] status*: SmallInt; field* : DWORD; end; pTs = POINTER TO TStatus; А как описан интерфейс функций Дельфи в модуле КП? |
Автор: | prospero78 [ Четверг, 15 Октябрь, 2015 09:26 ] |
Заголовок сообщения: | Re: Проблема: Delphi <--> CP |
Ну вот пришёл на работу, попытка №2 Всё-таки вместо DWORD -- в исходнике Word. Код: TADRtm = record Ch: SmallInt; RTU: SmallInt; Point: SmallInt; end; TStatusPoint = record Status: SmallInt; Flags: Word; end; pSP = ^TStatusPoint; Моя структура: Код: TYPE tAdrTm* = RECORD [untagged] (* Адрес ТМ *) ch*: SHORTINT; rtu*: SHORTINT; point*: SHORTINT; END; tStatusPoint* = RECORD [untagged] status*: SHORTINT; flags*: CHAR; END; tSp* = POINTER [untagged] TO tStatusPoint; В итоге ругается, что не можно сделать NEW для untagged. Что можно, я не разобрался) Результат вызова функции из ДЛЛ: Код: Отключение прошло успешно Соединение прошло успешно tmStatusFull: Запрос прошёл успешно = 1 #TC10:1:16= И окно отладки, при попытке прочитать поля структуры; окошко утверждает, что sp (который tSp*) -- NIL. Ответ чувствую, простой, но не догоняю. |
Автор: | prospero78 [ Четверг, 15 Октябрь, 2015 10:14 ] |
Заголовок сообщения: | Re: Проблема: Delphi <--> CP |
Попытался побаловаться с модулем SYSTEM: Код: adr_SP:=SYSTEM.ADR(_SP); (* получить адрес структуры*) adr_pTsp:=SYSTEM.ADR(SP); (* получить адрес указателя на структууы*) SYSTEM.PUT(adr_pTsp, adr_SP); (* сохранить в указателе адрес структуры *) Result:=p.tmStatusFull(adr, SP); SYSTEM.GET(adr_pTsp, _SP.status); StdLog.String('_SP.status='); StdLog.Int(_SP.status); StdLog.Ln; SYSTEM.GET(adr_pTsp+4, _SP.flags); StdLog.String('_SP.flags='); StdLog.Int(ORD(_SP.flags)); StdLog.Ln; Перестал отладчик ругаться на NIL, выдал волшебный результат, возможно из-за того, что [untagged]. Результат не меняется, в не зависимости от того, что я делаю с телепараметром. Видимо, промахиваюсь с ячейкой памяти. Как бы теперь подглядеть?))) Хм.... Есть у меня ломик.... |
Автор: | prospero78 [ Четверг, 15 Октябрь, 2015 12:00 ] |
Заголовок сообщения: | Re: Проблема: Delphi <--> CP |
Попытка прочитать значение указателя памяти [untagged] и структуры закончилась мусорным результатом. Что меняю телесигнал, что не меняю -- одинаково, (-10...+10) байт в памяти вокруг адреса -- не меняются. И что совсем подозрительно: адреса структуры без тега, и указателя на структуру без тэга -- разница всего 4 байта?.... Уж не идёт ли затирка данных? АДД. Добавил в структуру 3 поля CHAR, и вижу, что размер структуры стал все 10 байт. Значит без них было всего 4. Хм. А правильно ли это? Ведь в стек кладётся все 4 байта?... |
Автор: | prospero78 [ Четверг, 15 Октябрь, 2015 12:49 ] |
Заголовок сообщения: | Re: Проблема: Delphi <--> CP |
Продолжение детектива. Все поля в памяти располагаются "задом наперёд" -- чем ближе поле к началу -- тем меньше его адрес. А адрес последнего поля совпадает с адресом структуры untagged. |
Автор: | prospero78 [ Четверг, 15 Октябрь, 2015 13:06 ] |
Заголовок сообщения: | Re: Проблема: Delphi <--> CP |
Вопрос знатокам: а при описании параметров процедур в интерфейсном модуле -- типы SHORTINT, INTEGER и т. д. -- ссылаются на untagged типы или как? |
Автор: | prospero78 [ Четверг, 15 Октябрь, 2015 13:18 ] |
Заголовок сообщения: | Re: Проблема: Delphi <--> CP |
УРААААА!!!! Проблема с tmStatus решена!!!!!! Я в библиотеке параметрам подставляю untagged типы переменных SHORTINT! ))) |
Автор: | prospero78 [ Четверг, 15 Октябрь, 2015 13:50 ] |
Заголовок сообщения: | Re: Проблема: Delphi <--> CP |
Уря) Проблема с tmSetStatus решена))) (аналогично -- описание типов как untagged) Пример для таких как я: Код: TYPE
tByte* = RECORD [untagged] val* : BYTE; END; |
Автор: | Илья Ермаков [ Четверг, 15 Октябрь, 2015 14:31 ] |
Заголовок сообщения: | Re: Проблема: Delphi <--> CP |
Послушайте, Вам POINTER TO Status, в принципе, не нужен. Вы должны объявить на КП в сигнатуре процедуры (...., VAR pSt: Status) - это как раз эквивалентно передаче указателя. При условии, что библиотека не запоминает нигде этот адрес и не обращается по нему после вызова. Хотя даже в таком случае можно её будет натравить на глобальный в модуле VAR stat: Status, |
Автор: | prospero78 [ Четверг, 15 Октябрь, 2015 15:54 ] |
Заголовок сообщения: | Re: Проблема: Delphi <--> CP |
Ценный совет, спасибо. Сейчас попробую) Библиотека по передаваемой ссылке записывает свои данные и на этом всё. Ей эта память не интересна. Не могу передать в качестве аргумента пустую строку. Видимо, форматы отличаются. (* Хотя вообще глупость написал. При вызове tmSetStatus -- ARRAY OF SHORTCHAR -- вполне прокатывает. Такая же пустая строка *) After ADD. Указание VAR параметров работает, но возвращает почему-то (как и прежде) в tmAnalog() 3.402823466385289E+38 = MAX (SHORTREAL). After ADD2. Ах-ха-ха-ха.... )))) tmSetAnalog() работает вполне прилично)))) After ADD3. Вот я и выяснил, что tmAnalog() как INTEGER возвращает 0. Хм. К чему бы это?... |
Автор: | Роман М. [ Четверг, 15 Октябрь, 2015 17:55 ] |
Заголовок сообщения: | Re: Проблема: Delphi <--> CP |
prospero78 писал(а): Вопрос знатокам: а при описании параметров процедур в интерфейсном модуле -- типы SHORTINT, INTEGER и т. д. -- ссылаются на untagged типы или как? [untagged] означает инструкцию для сборщика мусора: память не резервировать, не освобождать, при указании на тип Запись обращать как к "чужой" структуре, без получения служебной информации о ней. prospero78 писал(а): Уря) Проблема с tmSetStatus решена))) (аналогично -- описание типов как untagged) Пример для таких как я: Код: TYPE tByte* = RECORD [untagged] val* : BYTE; END; Простые типы данных не нужно специально обворачивать в контейнеры типа Запись. Это излишне. К ним обращаются напрямую. Можно ли взглянуть на интерфейс в КП полностью? |
Автор: | prospero78 [ Четверг, 15 Октябрь, 2015 19:00 ] |
Заголовок сообщения: | Re: Проблема: Delphi <--> CP |
Роман М. писал(а): [Можно ли взглянуть на интерфейс в КП полностью? Ахтунг. Много букав. Код: MODULE AsduTmaccess ["tmaccess"]; TYPE tAdrTm* = RECORD [untagged] (* Адрес ТМ *) ch*: SHORTINT; rtu*: SHORTINT; point*: SHORTINT; END; tStatusPoint* = RECORD [untagged] status*: SHORTINT; flags*: CHAR; END; tAnalogPoint* = RECORD [untagged] asFloat*: SHORTREAL; asCode*: SHORTINT; Flags*: CHAR; Units*: ARRAY 10 OF SHORTCHAR; END; PROCEDURE tmInit*['_tmInit@8'](IN ServerName, LocalName: ARRAY OF SHORTCHAR): SHORTINT; PROCEDURE tmClose*['_tmClose@0'](): SHORTINT; PROCEDURE tmStatus*['_tmStatus@12'](Ch, RTU, Point: SHORTINT):SHORTINT; PROCEDURE tmSetStatus*['_tmSetStatus@24'](Ch, RTU, Point: SHORTINT; Value: BYTE; Time: ARRAY OF SHORTCHAR; Hund: SHORTINT): SHORTINT; PROCEDURE tmAnalog*['_tmAnalog@20'] (Ch, RTU, Point: SHORTINT; Time: ARRAY OF SHORTCHAR; RetroNum: SHORTINT): SHORTREAL; PROCEDURE tmSetAnalog*['_tmSetAnalog@20'] (Ch, RTU, Point: SHORTINT; Value: SHORTREAL; Time: ARRAY OF SHORTCHAR): SHORTINT; PROCEDURE tmAnalogFull*['_tmAnalogFull@24'] (Ch, RTU, Point: SHORTINT; VAR ap: tAnalogPoint; Time: ARRAY OF SHORTCHAR; RetroNum: SHORTINT): SHORTREAL ; PROCEDURE tmStatusFull*['_tmStatusFull@16'] (Ch, RTU, Point: SHORTINT; VAR SP: tStatusPoint):SHORTINT; END AsduTmaccess. Сейчас буду пробовать упрощать. По большому счёту, я эти типы понавводил чтобы приблизиться к оригиналу на Delphi Что совсем неприятно -- пишу один к одному на Delphi -- всё работает, зараза такая... Строго говоря, 5 из 6 процедур работают. Мне нужна теперь только tmAnalog, либо tmAnalogFull. При попытке выполнить tmAnalog вывод: tmAnalog= 3.402823466385289E+38 При попытке выполнить tmAnalogFull вылетает отладчик с милым сообщением: undefined real result (81E3, 37E) |
Автор: | Alexander Shiryaev [ Четверг, 15 Октябрь, 2015 20:32 ] |
Заголовок сообщения: | Re: Проблема: Delphi <--> CP |
Цитата: flags: CHAR CHAR лучше заменить на SHORTINT (Delphi Word → Component Pascal SHORTINT). Все массивы должны быть с флагом untagged (ARRAY ... OF → ARRAY [untagged] ... OF). Скорее всего надо заменить Time: ARRAY OF SHORTCHAR → VAR Time: ARRAY [untagged] OF SHORTCHAR (как в Delphi?) Delphi Single → Component Pascal SHORTREAL Delphi Double → Component Pascal REAL Типа Delphi Real в Component Pascal нет |
Автор: | prospero78 [ Четверг, 15 Октябрь, 2015 21:14 ] |
Заголовок сообщения: | Re: Проблема: Delphi <--> CP |
В оригинале вместо char используется word. Я не уверен, что передача флагов будет работать верно. Массивы там вообще никак не влияют, но за совет спасибо. У уже написал переходную DLL на Delphi и выяснил, что DLL сама не принимает из оригинальной DLL значение. Хотя оконное приложение прекрасно получает эти значения. Код: VAR Time: ARRAY OF SHORTCHAR <-- разве это не будет обращение по ссылке?
|
Страница 1 из 2 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |