OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Четверг, 28 Март, 2024 22:08

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




Начать новую тему Эта тема закрыта, вы не можете редактировать и оставлять сообщения в ней.  [ Сообщений: 27 ]  На страницу 1, 2  След.
Автор Сообщение
 Заголовок сообщения: Проблема: Delphi <--> CP
СообщениеДобавлено: Среда, 14 Октябрь, 2015 20:37 
Аватара пользователя

Зарегистрирован: Воскресенье, 12 Апрель, 2015 18:12
Сообщения: 1134
Откуда: СССР v2.0 rc 1
Есть уже готовый сервер телемеханики у нас на подстанции. Написан на 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. Нет желания проприетарщину гонять.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема: Delphi <--> CP
СообщениеДобавлено: Среда, 14 Октябрь, 2015 20:54 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Почитайте в доке ББ раздел Платформенно-зависимые особенности.

Нужно RECORD, соответствующий чужим структурам, объявлять как [untagged].


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема: Delphi <--> CP
СообщениеДобавлено: Среда, 14 Октябрь, 2015 20:58 

Зарегистрирован: Четверг, 17 Ноябрь, 2005 11:51
Сообщения: 2935
Откуда: г. Ярославль
Надо делать через [untagged] RECORD, на форуме много было обсуждений этого.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема: Delphi <--> CP
СообщениеДобавлено: Среда, 14 Октябрь, 2015 21:13 
Аватара пользователя

Зарегистрирован: Воскресенье, 12 Апрель, 2015 18:12
Сообщения: 1134
Откуда: СССР v2.0 rc 1
Я уже пробовал untagged. Не помогло.

Сейчас, пока ел, подумал, почему я DWORD и CHAR приравнял?

Хорошо бы где-то информации накопать по размерам типов в Delphi)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема: Delphi <--> CP
СообщениеДобавлено: Среда, 14 Октябрь, 2015 21:23 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
word - 16 бит.
DWORD, соответственно (он вообще WinApi-вский, по-моему) - 32. Как и Cardinal.

Т.е. неправильно приравняли.

Shortint сколько бит в дельфе? 16?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема: Delphi <--> CP
СообщениеДобавлено: Среда, 14 Октябрь, 2015 21:28 
Аватара пользователя

Зарегистрирован: Воскресенье, 12 Апрель, 2015 18:12
Сообщения: 1134
Откуда: СССР v2.0 rc 1
SmallInt -- да. 16 бит. -32000....+32000.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема: Delphi <--> CP
СообщениеДобавлено: Четверг, 15 Октябрь, 2015 01:58 

Зарегистрирован: Пятница, 25 Сентябрь, 2009 13:10
Сообщения: 1177
Откуда: Мариуполь
Для примера можно посмотреть исходник модуля 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;

А как описан интерфейс функций Дельфи в модуле КП?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема: Delphi <--> CP
СообщениеДобавлено: Четверг, 15 Октябрь, 2015 09:26 
Аватара пользователя

Зарегистрирован: Воскресенье, 12 Апрель, 2015 18:12
Сообщения: 1134
Откуда: СССР v2.0 rc 1
Ну вот пришёл на работу, попытка №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. Ответ чувствую, простой, но не догоняю.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема: Delphi <--> CP
СообщениеДобавлено: Четверг, 15 Октябрь, 2015 10:14 
Аватара пользователя

Зарегистрирован: Воскресенье, 12 Апрель, 2015 18:12
Сообщения: 1134
Откуда: СССР v2.0 rc 1
Попытался побаловаться с модулем 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].
Результат не меняется, в не зависимости от того, что я делаю с телепараметром. Видимо, промахиваюсь с ячейкой памяти. Как бы теперь подглядеть?))) Хм.... Есть у меня ломик....


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема: Delphi <--> CP
СообщениеДобавлено: Четверг, 15 Октябрь, 2015 12:00 
Аватара пользователя

Зарегистрирован: Воскресенье, 12 Апрель, 2015 18:12
Сообщения: 1134
Откуда: СССР v2.0 rc 1
Попытка прочитать значение указателя памяти [untagged] и структуры закончилась мусорным результатом.
Что меняю телесигнал, что не меняю -- одинаково, (-10...+10) байт в памяти вокруг адреса -- не меняются.
И что совсем подозрительно: адреса структуры без тега, и указателя на структуру без тэга -- разница всего 4 байта?....
Уж не идёт ли затирка данных?

АДД. Добавил в структуру 3 поля CHAR, и вижу, что размер структуры стал все 10 байт. Значит без них было всего 4. Хм. А правильно ли это? Ведь в стек кладётся все 4 байта?...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема: Delphi <--> CP
СообщениеДобавлено: Четверг, 15 Октябрь, 2015 12:49 
Аватара пользователя

Зарегистрирован: Воскресенье, 12 Апрель, 2015 18:12
Сообщения: 1134
Откуда: СССР v2.0 rc 1
Продолжение детектива.
Все поля в памяти располагаются "задом наперёд" -- чем ближе поле к началу -- тем меньше его адрес.
А адрес последнего поля совпадает с адресом структуры untagged.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема: Delphi <--> CP
СообщениеДобавлено: Четверг, 15 Октябрь, 2015 13:06 
Аватара пользователя

Зарегистрирован: Воскресенье, 12 Апрель, 2015 18:12
Сообщения: 1134
Откуда: СССР v2.0 rc 1
Вопрос знатокам: а при описании параметров процедур в интерфейсном модуле -- типы SHORTINT, INTEGER и т. д. -- ссылаются на untagged типы или как?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема: Delphi <--> CP
СообщениеДобавлено: Четверг, 15 Октябрь, 2015 13:18 
Аватара пользователя

Зарегистрирован: Воскресенье, 12 Апрель, 2015 18:12
Сообщения: 1134
Откуда: СССР v2.0 rc 1
УРААААА!!!!
Проблема с tmStatus решена!!!!!!
Я в библиотеке параметрам подставляю untagged типы переменных SHORTINT! )))


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема: Delphi <--> CP
СообщениеДобавлено: Четверг, 15 Октябрь, 2015 13:50 
Аватара пользователя

Зарегистрирован: Воскресенье, 12 Апрель, 2015 18:12
Сообщения: 1134
Откуда: СССР v2.0 rc 1
Уря)
Проблема с tmSetStatus решена))) (аналогично -- описание типов как untagged)
Пример для таких как я:
Код:
   TYPE
      tByte* = RECORD [untagged]
         val* : BYTE;
      END;


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема: Delphi <--> CP
СообщениеДобавлено: Четверг, 15 Октябрь, 2015 14:31 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Послушайте, Вам POINTER TO Status, в принципе, не нужен.

Вы должны объявить на КП в сигнатуре процедуры (...., VAR pSt: Status) - это как раз эквивалентно передаче указателя.

При условии, что библиотека не запоминает нигде этот адрес и не обращается по нему после вызова.
Хотя даже в таком случае можно её будет натравить на глобальный в модуле VAR stat: Status,


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема: Delphi <--> CP
СообщениеДобавлено: Четверг, 15 Октябрь, 2015 15:54 
Аватара пользователя

Зарегистрирован: Воскресенье, 12 Апрель, 2015 18:12
Сообщения: 1134
Откуда: СССР v2.0 rc 1
Ценный совет, спасибо. Сейчас попробую)
Библиотека по передаваемой ссылке записывает свои данные и на этом всё. Ей эта память не интересна.

Не могу передать в качестве аргумента пустую строку. Видимо, форматы отличаются.

(* Хотя вообще глупость написал. При вызове tmSetStatus -- ARRAY OF SHORTCHAR -- вполне прокатывает. Такая же пустая строка *)

After ADD. Указание VAR параметров работает, но возвращает почему-то (как и прежде) в tmAnalog() 3.402823466385289E+38 = MAX (SHORTREAL).

After ADD2. Ах-ха-ха-ха.... )))) tmSetAnalog() работает вполне прилично))))

After ADD3. Вот я и выяснил, что tmAnalog() как INTEGER возвращает 0. Хм. К чему бы это?...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема: Delphi <--> CP
СообщениеДобавлено: Четверг, 15 Октябрь, 2015 17:55 

Зарегистрирован: Пятница, 25 Сентябрь, 2009 13:10
Сообщения: 1177
Откуда: Мариуполь
prospero78 писал(а):
Вопрос знатокам: а при описании параметров процедур в интерфейсном модуле -- типы SHORTINT, INTEGER и т. д. -- ссылаются на untagged типы или как?

[untagged] означает инструкцию для сборщика мусора: память не резервировать, не освобождать, при указании на тип Запись обращать как к "чужой" структуре, без получения служебной информации о ней.

prospero78 писал(а):
Уря)
Проблема с tmSetStatus решена))) (аналогично -- описание типов как untagged)
Пример для таких как я:
Код:
   TYPE
      tByte* = RECORD [untagged]
         val* : BYTE;
      END;

Простые типы данных не нужно специально обворачивать в контейнеры типа Запись. Это излишне. К ним обращаются напрямую.

Можно ли взглянуть на интерфейс в КП полностью?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема: Delphi <--> CP
СообщениеДобавлено: Четверг, 15 Октябрь, 2015 19:00 
Аватара пользователя

Зарегистрирован: Воскресенье, 12 Апрель, 2015 18:12
Сообщения: 1134
Откуда: СССР v2.0 rc 1
Роман М. писал(а):
[Можно ли взглянуть на интерфейс в КП полностью?

Ахтунг.
Много букав.
Код:
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)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема: Delphi <--> CP
СообщениеДобавлено: Четверг, 15 Октябрь, 2015 20:32 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 02:12
Сообщения: 473
Откуда: KZ
Цитата:
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 нет


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема: Delphi <--> CP
СообщениеДобавлено: Четверг, 15 Октябрь, 2015 21:14 
Аватара пользователя

Зарегистрирован: Воскресенье, 12 Апрель, 2015 18:12
Сообщения: 1134
Откуда: СССР v2.0 rc 1
В оригинале вместо char используется word.
Я не уверен, что передача флагов будет работать верно.

Массивы там вообще никак не влияют, но за совет спасибо.

У уже написал переходную DLL на Delphi и выяснил, что DLL сама не принимает из оригинальной DLL значение.
Хотя оконное приложение прекрасно получает эти значения.

Код:
VAR Time: ARRAY OF SHORTCHAR
<-- разве это не будет обращение по ссылке?


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Эта тема закрыта, вы не можете редактировать и оставлять сообщения в ней.  [ Сообщений: 27 ]  На страницу 1, 2  След.

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


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

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


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

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