![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Динамическая библиотека и указатель. [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 - то предусмотри в ней функцию освобождения. Если в хост-приложении - переделай функцию в процедуру, передавай указатель на структуру с уже выделенной памятью