OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Суббота, 27 Апрель, 2024 19:29

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




Начать новую тему Ответить на тему  [ Сообщений: 51 ]  На страницу 1, 2, 3  След.
Автор Сообщение
СообщениеДобавлено: Четверг, 12 Январь, 2006 18:49 

Зарегистрирован: Понедельник, 28 Ноябрь, 2005 18:08
Сообщения: 76
Пробовал оборачивать netapi32.dll. Пока неудачно.
Код:
MODULE NBSInterface ["netapi32.dll"];

.....

TYPE
   
      Handle = INTEGER;
      
      TNBName = ARRAY NBNAMESIZE - 1 OF BYTE;
      TNCBPostProc = PROCEDURE(P: PNCB);

      PNCB* = POINTER TO TNCB;
      TNCB* =  RECORD [noalign]
         Command*:  BYTE;
         RetCode*:  BYTE;     
         LSN*:      BYTE;     
         Num*:      BYTE;     
         Buf*:      INTEGER;   
         Length*:   INTEGER;   
         CallName*: TNBName;   
         Name*:     TNBName;   
         RTO*:      BYTE;     
         STO*:      BYTE;     
         PostPrc*:  TNCBPostProc;

         Lana_Num*: BYTE;   
         Cmd_Cplt*: BYTE;     

         Reserved*: ARRAY 10 OF BYTE;
         Event*:    Handle; 

  END;
      
      
      
   PROCEDURE Netbios* (P:PNCB): CHAR;
END NBSInterface.


Код на Delphi:
Код:
  PNCB = ^TNCB;

 { Netbios Control Block }

 {$IFDEF WIN32}
  TNCBPostProc = procedure(P: PNCB);
 {$ENDIF}

  TNCB = packed record        { Netbios Control Block }
    Command:  byte;      { command code                       }
    RetCode:  byte;      { return code                        }
    LSN:      byte;      { local session number               }
    Num:      byte;      { name number                        }
    Buf:      ^byte;     { data buffer                        }
    Length:   word;      { data length                        }
    CallName: TNBName;   { name to call                       }
    Name:     TNBName;   { our own name                       }
    RTO:      byte;      { receive time-out                   }
    STO:      byte;      { send time-out                      }
  {$IFNDEF WIN32}
    Post_Offs:word;      { asynch notification routine offset }
    Post_Seg: word;      { asynch notification routine segment}
  {$ELSE}
    PostPrc:  TNCBPostProc;{ asynch notification routine (nb30) }
  {$ENDIF}
    Lana_Num: byte;     { adapter number                     }
    Cmd_Cplt: byte;     { command completion flag            }
  {$IFDEF WIN32}
    Reserved: array[0..9] of byte;  { Reserverd for Bios use }
    Event:    THandle;  { WIN32 event handle to be signalled }
                        { for asynch cmd completion          }
  {$ELSE}
    Reserved: array[0..13] of byte;  { Reserved }
  {$ENDIF}
  end;


Сомневаюсь, что правильно описал Buf.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 12 Январь, 2006 21:49 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
TNBName = ARRAY [untagged] NBNAMESIZE - 1 OF BYTE;
- здесь, строго говоря, тоже надо влепить [untagged]. Хотя память под массив динамически и не выделяется, но тег все равно будет даже у поля записи - например, для работы SIZE() при передаче открытым массивом.
Еще возможно, хотя не уверен, без [noalign] будет 4-байтовое выравнивание на элементы массива. Лучше в данном случае вообще использовать SHORTCHAR.

Buf как раз верен: для системных указателей используется INTEGER.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 12 Январь, 2006 23:31 

Зарегистрирован: Вторник, 29 Ноябрь, 2005 21:41
Сообщения: 1030
Сомнение вызывает тип у Length. SHORTINT подходит больше. А нельзя не переводить недостающие типы, а новые добавлять к базовым?
P.S. Жаль только комментарии пропадают куда-то.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 12 Январь, 2006 23:52 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Цитата:
Сомнение вызывает тип у Length. SHORTINT подходит больше.


Да, кстати! Проглядел - Length действительно должен быть SHORTINT.
Тут никаких "больше-меньше подходит", тут же нарушалась вся структура из-за 32-битного INTEGER вместо 16-битного word. Правда, SHORTINT не полностью соответствует word - он знаковый, но тут уж ничего не попишешь, нет в КП беззнаковых целых...

Reserved*: ARRAY 10 OF BYTE - надо [untagged]


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пятница, 13 Январь, 2006 06:28 

Зарегистрирован: Вторник, 29 Ноябрь, 2005 21:41
Сообщения: 1030
Илья, разница между больше подходит и должен такая же, как между SHORTINT и WORD. Но раз последний отсутствует в языке, то писать придется, увы. Вообще-то заменить ARRAY на запись с байтовыми полями и орудовать на низком уровне. Такая возможность всегда остается.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пятница, 13 Январь, 2006 10:13 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 12:02
Сообщения: 8500
Откуда: Троицк, Москва
Илья Ермаков писал(а):
TNBName = ARRAY [untagged] NBNAMESIZE - 1 OF BYTE;
... Еще возможно, хотя не уверен, без [noalign] будет 4-байтовое выравнивание на элементы массива.


Но не для BYTE и не для SHORTINT|CHAR (конечно же).


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 13 Январь, 2006 11:10 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 18:55
Сообщения: 2272
Откуда: Россия, Нижний Новгород
Cardinal писал(а):
Код:
PROCEDURE Netbios* (P:PNCB): CHAR;

Признаться честно, не понимаю о чём речь, но о чём бы она ни была, мне кажется, что одна ошибка видна невооруженным взглядом. Процедура Netbios не выделяет память под объект (не меняет значения указателя). Значит ей надо передавать не указатель (не POINTER TO), а адрес ранее размещенного объекта (адрес передаётся с помощью ссылочного модификатора IN, VAR или OUT):
Код:
PROCEDURE Netbios* (VAR ncb: TNCB): CHAR;

Код:
  VAR ncb: TNCB;
BEGIN
  ...
  Netbios(ncb);
  ...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пятница, 13 Январь, 2006 14:04 

Зарегистрирован: Понедельник, 28 Ноябрь, 2005 10:28
Сообщения: 1429
А почему NBNAMESIZE - 1 ?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пятница, 13 Январь, 2006 14:12 

Зарегистрирован: Понедельник, 28 Ноябрь, 2005 10:28
Сообщения: 1429
Кстати, Вы смотрели WinNet? Кажется, там уже есть интерфейс к netbios.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пятница, 13 Январь, 2006 15:29 

Зарегистрирован: Понедельник, 28 Ноябрь, 2005 18:08
Сообщения: 76
Сейчас посмотрел. То, что надо. Спасибо :wink: . А мой пример после внесения всех изменений, которые здесь мне советовали, выдавал Illegal command.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пятница, 13 Январь, 2006 20:39 

Зарегистрирован: Вторник, 29 Ноябрь, 2005 21:41
Сообщения: 1030
Признаться честно, я не понял, может ли значение типа указатель отличаться от адреса ранее размещенного объекта...
С чем связано то, что указатели по значению не передаются?


Последний раз редактировалось Сергей Оборотов Пятница, 13 Январь, 2006 23:17, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пятница, 13 Январь, 2006 23:08 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 18:55
Сообщения: 2272
Откуда: Россия, Нижний Новгород
GUEST писал(а):
Признаться честно, я не понял,...


Работая с самим объектом ncb: TNCB в отличие от указателя на него ptr: PNCB, не надо заботится о размещении в памяти объекта ptr^ на который он указывает. В случае [untagged] объекта разместить его в памяти с помощью NEW(ptr) нельзя, а это, согласитесь, дополнительные проблемы. Ссылочные модификаторы IN, VAR и OUT позволяют передавать адрес объекта в WinApi-шные процедуры не используя указателей вовсе.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пятница, 13 Январь, 2006 23:30 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Цитата:
С чем связано то, что указатели по значению не передаются?



С тем, что по ссылке можно передать как статическую переменную, так и указатель - он будет разыменован (формально говоря, на самом деле, конечно, парам-р по ссылке - это и есть указатель, и с точки зрения машинного кода операция лишняя возникает как раз в первом случае - взятие адреса).

Так вот, а в ту процедуру, которая требует указателя, статическую переменную вы не передадите никак - в КП отсутствует операция взятия адреса, т.к. она порождает небезопасные (неуправляемые) указатели. Есть, конечно, SYSTEM.ADR - но это низкоуровневая вещь, которой нужно пользоваться как можно меньше.

Кстати, я как-то собрался написать функцию, которая безопасно берет адрес от переменной, переданной по ссылке, проверяя перед этим, что переменная находится именно в куче, а не в стеке и не в глобальной секции модуля. Проверить все эти условия удалось, но не удалось одного: проверить, что переменная распределена в куче самостоятельно, а не как поле другой динамической переменной. А без такой проверки вся безопасность летит куда подальше - если сборщик мусора уберет часть другой записи... бр... От затеи пришлось отказаться, да и не особенно она нужна была...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пятница, 13 Январь, 2006 23:33 

Зарегистрирован: Вторник, 29 Ноябрь, 2005 21:41
Сообщения: 1030
А почему надо заботиться о размещении в памяти объекта, на который указывает ptr. Нет возможности просто указать с каким объектом ему работать?
Можно также спросить на какой вопрос вы отвечали?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пятница, 13 Январь, 2006 23:43 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Цитата:
А почему надо заботиться о размещении в памяти объекта, на который указывает ptr. Нет возможности просто указать с каким объектом ему работать?


Тогда я не понимаю вопроса...

Смотрите:

PROCEDURE Netbios* (P:PNCB): CHAR;

Если процедура объявляется так, то в точке ее вызова мне придется откуда-то брать динамически распределенный NCB. Или брать SYSTEM.ADR от стековой переменной и приводить его тип через SYSTEM.VAL. Но использовать SYSTEM в "нормальном" коде не следует вообще - это и несовместимость, и нарушение безопасности. А откуда мне взять динамически распределенный NCB? NEW с [untagged]-записями не работает, значит, нужно обращаться к WinApi.VirualAlloc или системному менеджеру кучи. А потом прибивать эту память. Целый букет гемора + потеря скорости.

Если я объявляю PROCEDURE Netbios* (VAR ncb: TNCB): CHAR, то
я могу сделать как
VAR ncb: NCB; BEGIN Netbios(ncb),
так и VAR pncd: PNCB; ... Netbios(pncb).
То есть, получаем штатный вариант, работающий с любой памятью, при том безопасно.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пятница, 13 Январь, 2006 23:46 

Зарегистрирован: Вторник, 29 Ноябрь, 2005 21:41
Сообщения: 1030
Я впрочем, и не хотел передавать в процедуру статическую переменную, а лишь значение указателя. Могу я это сделать?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пятница, 13 Январь, 2006 23:56 
Модератор
Аватара пользователя

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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Суббота, 14 Январь, 2006 00:15 

Зарегистрирован: Вторник, 29 Ноябрь, 2005 21:41
Сообщения: 1030
Извините, пожалуйста, в мою цель не входило выявить предпочтительный способ задания процедур.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Суббота, 14 Январь, 2006 00:26 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Пардон, мне показалось, что вначале Вы спрашивали именно это, после замечания Губанова по форме процедур... Может быть, перепутал...


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 14 Январь, 2006 08:13 

Зарегистрирован: Вторник, 29 Ноябрь, 2005 21:41
Сообщения: 1030
Сергей Губанов писал(а):
Cardinal писал(а):
Код:
PROCEDURE Netbios* (P:PNCB): CHAR;
...
, мне кажется, что одна ошибка видна невооруженным взглядом. Процедура Netbios не выделяет память под объект (не меняет значения указателя). Значит ей надо передавать не указатель (не POINTER TO), а адрес ранее размещенного объекта
Цитата:
Признаться честно, я не понял, может ли значение типа указатель отличаться от адреса ранее размещенного объекта...
...?


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

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


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

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


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

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