Device Manage for OS/2

DevCon for OS/2 - Developer Connection

Operating systems:
ArcaOS, eComStation, IBM OS/2 Warp
Мифы о eComStation 

(Unsorted)  
 
 
Compilers  
 
 
Tools  
 
 
User Interface  
 
 
REXX  
 
 
Drivers/kernel  
 
 

 

 

Требования к dll / Какие правила соблюдать при проектировании API?

В первом приближении
  • Функции должны экспортироваться по ординалам.
  • К dll должен прилагаться .h-файл с описанием функций
  • Если интерфейс опубликован, то менять его нельзя. Если нужны новые функции, исправленные, то добавляй их как новые.
Не возвращать указатели Функции, сообщения, методы и прочие структуры API не должны возвращать указатели. Предпочитаемый вариант - использование хэндлов. Функции (и пр.) не должны выделять внутри себя память и отдавать ее клиентскому приложению. Память имеет право выделять только клиентское приложение, оно же и ответственно за ее освобождение. Пример такого подхода см. в OS/2 Toolkit. Исключением являются функции класса malloc, DosAllocMem и пр.
Возможность расширять структуры в будущем Структуры данных должны позволять в дальнейшем вводить новые поля. Т.е. каждый составной тип первым полем должен иметь переменную с информацией о размере структуры. Примеры см. в OS/2 Toolkit. При передаче клиентом в функцию структуры (буфера) меньшей длины, структура должна заполняться частично. Т.е. если API использовал ранее структуру типа:
       
      struct DemoType1 {
        USHORT size;
        LONG item1;
      };

А потом стал использовать

      struct DemoType2 {
        USHORT size;
        LONG item1;
        PSZ item2;
      };

То при передаче клиентом буфера размером sizeof(DemoType1) должны быть заполнены поля по Item1 (включительно), несмотря на то, что функция API может заполнить и более полную структуру.

Зафиксируйте выравнивание Если в аргументах функции передаются структуры, то обязательно зафиксируйте выравнивание, .h файл должен содержать:
#pragma pack(4)

pack(1) может использоваться:

  • только тогда когда речь идет к примеру, о структуре базы данных или сетевого пакета
  • при работе с "железом" (оборудованием)
  • при обмене данными с многоплатформенными "черными ящиками" (т.е. с кодом, который также работает в Windows/Linux)

ВНИМАНИЕ: Если меняете значение pragma pack в начале .h файла, то не забывайте вернуть дефолтное значение в конце .h файла:

#pragma pack()
Export by ordinals, not names

Экспортировать надо всегда по ординалам (чтобы старые программы работали с новыми версиями .dll). Импортировать надо всегда по имени, а не по ординалам.

OpenWatcom, wlink.exe

Добавьте в .def на линковку dll:

EXPORTS
    RegisterPluginProc  @501 NONAME

если в makefile, то

export VfmParserVersion.1

Visual Age for C, v.4

   option link(export, "PLINIT",,1,NONAME)
Простой Си Не используйте C++ внутри dll
Неожиданность Вызовы функций abort, exit в модулях недопустимы.
Параметры: char * или const char* Если аргумент функции объявлен как char*, а не const char*, то этот аргумент может быть изменен этой функцией. Ну и, собственно, в самой функции случайно можно ошибиться и угробить строку. Для этого const и придуман.

Useful functions

Check dll presence:

APIRET CheckDll(PSZ pszModname)
{
    HMODULE hmod;
    char    szPath[CCHMAXPATH];
    APIRET  rc;

    rc = DosLoadModule( szPath, sizeof(szPath), pszModname, &hmod);
    if (!rc)
       DosFreeModule( hmod);
    return (rc);
} 

Useful tools

  • which dll -- find the active instance of a DLL
  • pmdll -- view DLL dependencies of OS/2 executables

 


 

(C) OS2.GURU 2001-2024