Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Динамическая библиотека и указатель. [D6, WinXP]


novice_man ©   (2005-01-27 17:54:00) 

Уважаемые мастера, вот наткнулся:
вызываю функцию из библиотеки:

function GetINFO(FolderCFG: ShortString): pInfoData; StdCall; export;
begin
New(Result);
Result^.name_service := 'xxxxxxxxxxxx';
Result^.type_service := 1;
end;

где, type
      pInfoData = ^tInfoData;
      tInfoData = record
                  name_service: String[25];
                  type_service: byte;
      end;

вызов
var
 INFO_data: pInfoData;
 nDLL: THandle;
 fGetINFO: function(FolderCFG: ShortString): pInfoData; StdCall;
begin
hDLL := LoadLibrary('service.dll');
if hDLL <> 0 then begin
   @fGetINFO := nil;
   @fGetINFO := GetProcAddress(hDevice, 'GetINFO');
   if @fGetINFO <> nil then INFO_data := fGetINFO;
   FreeLibrary(hDLL);
   end;
end;

в общем класика, но вот только я пытаюсь обратиться к полям pInfoData (INFO_data^.name_service, INFO_data^.type_service), так AV..., при этом проверка Assigned(INFO_data) = true !?
Но если результатом библиотечной функции будет tInfoData (естественно переписав все под tInfoData), то все нормально.

ВОПРОС: если я не прав, то где, объясните пожалуйста.

З.Ы. ShareMem не использовался, нет длинных строк и динамических массивов.


REA   (2005-01-28 10:04:00) [1]

>при этом проверка Assigned(INFO_data) = true !?

А где оно присваивется в Nil? Может INFO_data := fGetINFO просто и не вызывается.


Юрий Зотов   (2005-01-27 22:08:00) [2]

> novice_man ©   (27.01.05 20:35) [4]

А разве в [1] сказано не то же самое?


novice_man   (2005-01-27 20:35:00) [3]

Alexander Panov ©   (27.01.05 19:43) [3]
Спасибо за дельный совет. Так и стану делать.


Alexander Panov   (2005-01-27 19:43:00) [4]

Поступай так, как это делается во многих функциях WIN32API:
1. выделяй память под запись в основном модуле
2. передавай указатель на запись в функцию
3. в dll заполняй эту запись.
4. в основном модуле освобождай память из-под записи.


novice_man   (2005-01-27 19:23:00) [5]

MBo ©   (27.01.05 18:27) [1]

Пробовал перед получением результата из функции dll инициализировать переменную "приемник" \
  ....
  @fGetINFO := nil;
  @fGetINFO := GetProcAddress(hDevice, 'GetINFO');
  if @fGetINFO <> nil then begin
     New(INFO_data);
     INFO_data := fGetINFO;
     end;
  ....

результат аналогичный.

И еще как освободить память из-под переменной если она result функции?

Да и ошибка описанная Вам у меня обычно возникала когда я выгружал библиотеку, то есть когда происходило освобождение ресурсов, а тут выгрузка происходит нормально.

hDLL := LoadLibrary('service.dll');
try

finally if hDll <> 0 then FreeLibrary(hDLL); end;

у меня так, и все работает.


MBo   (2005-01-27 18:27:00) [6]

Выделять и освобождать память стоит в одном месте. Если в DLL - то предусмотри в ней функцию освобождения. Если в хост-приложении - переделай функцию в процедуру, передавай указатель на структуру с уже выделенной памятью


Наверх

Титульная страница Поиск, карта сайта Написать письмо