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

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

Динамический импорт функции из DLL [D7]


Страницы:   1 2

Igit ©   (2005-06-23 11:43:00) 

Здравтсвйте мастера! Есть у меня одлин модуль, в нем описываются функции вызываемые из NTDLL.DLL...  они видны в таблице импорта... и из-за них под вин9x программа не запускается вовсе... (у меня в программе идет проверка какая винда и в зависимости от этого исп. тот или иной метод). Так вот, как можно переписать например вот это

Function DbgUiConnectToDbg(): NTStatus;stdcall;external 'ntdll.dll';

на такое чтоб не жестко привязывалось к ntdll а динамически?


Igit   (2005-06-23 13:04:00) [21]

-=XP=- Если модуль имеет объявления extrnal процедур/функций - то библиотека будет загружена автоматически при запуске приложения; если библиотека не обнаружится на компьютере

NativeAPI в NT берутся из ntdll... все АПИ используют NativeAPI, значит в NT она по идее загружена всегда.


-=XP=-   (2005-06-23 12:56:00) [22]

GetModuleHandle() просто ищет модуль в АП процесса, возвращает его хэндл ( в случае с НТ - гарантированно)

Почему?


-=XP=-   (2005-06-23 12:54:00) [23]

она ведь в NT всегда загружена

Библиотека загружается или динамически (LoadLibrary) или статически (с указанием external).
Если модуль имеет объявления extrnal процедур/функций - то библиотека будет загружена автоматически при запуске приложения; если библиотека не обнаружится на компьютере - приложение не запустится никогда. Если нет явного указания (статического) использования внешних процедур/функций из этой библиотеки - она (библиотека) не будет загружена автоматически никогда. Для динамической загрузки используйте LoadLibrary.

Резюмируя: хотите кроссплатформенности - используйте динамическую загрузку библиотек; использование статического подключения библиотек, при отсутствии оных на компьютрере пользователя, вызовет аварийное завершение работы программы.


Digitman   (2005-06-23 12:52:00) [24]


> может неоязательно загружать библиотеку ntdd, она ведь в
> NT всегда загружена?


может и необязательно.

GetModulehandle() в дан.случае даст тот же результат, что и LoadLibrary()

разница в дан.случае практически неощутима - Load/FreeLibrary() инкрементирует/декрементирует некий (детали неважны) внутрисистемный сч-к использования библ-ки, кроме собссно ее штатной загрузки/иниц-ии/деиниц-ции/выгрузки, в то время как GetModuleHandle() просто ищет модуль в АП процесса, возвращает его хэндл (в случае с НТ - гарантированно), и этот хэндл в любой момент можно передать на вход GetProcAddress(), без опасений ан тему неактуальности в некий момент времени полученного адреса.


Igit   (2005-06-23 12:44:00) [25]

Я не доконца понял, но навязался такой вопрос, может он глупый, но возник :) Т.к. функции в этом модуле вызываются только если запущена WinNT, то может неоязательно загружать библиотеку ntdd, она ведь в NT всегда загружена?


-=XP=-   (2005-06-23 12:37:00) [26]

stdcall; - естественно, тоже указать. :)


-=XP=-   (2005-06-23 12:34:00) [27]

unit SuUnit;

interface

uses
Windows;

type
TZwCreateThread = function(ThreadHandle: pdword;
                      DesiredAccess: ACCESS_MASK;
                      ObjectAttributes: pointer;
                      ProcessHandle: THandle;
                      ClientId: PClientID;
                      ThreadContext: pointer;
                      UserStack: pointer;
                      CreateSuspended: boolean):NTStatus;
                      stdcall;

var
 ZwCreateThread: TZwCreateThread;

implementation

end.


Только вот библиотеку загрузить надо. И указатель на функцию получить. В противном случае, при использовании неинициализированной процедурной переменной будет вызван Access Violation. Когда это (загрузку) сделать - Ваше дело. Главное, чтобы это было сделано допервого использования функции. Ну, или в любом месте, где используется эта функция - делать проверку:

if Assigned(ZwCreateThread) then ZwCreateThread({параметры});

Но, судя по вопросу - такая проверка невозможна.

Поэтому, можете пойти по другому пути - написать "подставную" функцию, возвращающую "подставной" результат. В разделе инициализации модуля написать:

implementation

function ZwCreateThread_Int({параметры}): NTStatus;
begin
 // Не забудьте определить возвращаемые значения
end;

initialization
 ZwCreateThread := @ZwCreateThread_Int;

end;


А если потом удастся загрузить внешнюю библиотеку - будете пользоваться ею.


Igit   (2005-06-23 12:16:00) [28]

Я запутался... =(

Вот есть примерный модуль.

unit SuUnit;

interface
  uses windows;

////////////////////////// Ntdll.dll Functions ///////////////////////

Function ZwCreateThread(ThreadHandle: pdword;
                       DesiredAccess: ACCESS_MASK;
                       ObjectAttributes: pointer;
                       ProcessHandle: THandle;
                       ClientId: PClientID;
                       ThreadContext: pointer;
                       UserStack: pointer;
                       CreateSuspended: boolean):NTStatus;
                       stdcall;external 'ntdll.dll';

implementation

end.

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


-=XP=-   (2005-06-23 12:12:00) [29]

Э-э-э... А stdcall не помешает?

Э-э-э-э... естественно. :)
Для пущей надежности - safecall.

В контексте, автору:

TDbgUiConnectToDbg = function({параметры}): NTStatus; stdcall; {safecall;}


begin...end   (2005-06-23 12:04:00) [30]

> -=XP=- ©   (23.06.05 11:53) [2]

Э-э-э... А stdcallне помешает?


Igit   (2005-06-23 12:02:00) [31]

Все, понял, буду разбираться, спасибо!


-=XP=-   (2005-06-23 11:53:00) [32]

type
 TDbgUiConnectToDbg = function({параметры}): NTStatus; // Обявление процедурного типа

var
 Lib: THandle;
 DbgUiConnectToDbg: TDbgUiConnectToDbg; // "Будущая" процедура/функция
 Status: NTStatus;
begin
 Lib := LoadLibrary('ntdll.dll'); // Загрузка библиотеки
 if Lib <> 0 then // Если удачно, то
 try
   DbgUiConnectToDbg := GetProcAddress(Lib, 'DbgUiConnectToDbg'); // Получение адреса процедуры/функции
   if Assigned(DbgUiConnectToDbg) then // Если процедура/функция найдена (адрес задан)
     Status := DbgUiConnectToDbg({параметры}); // Вызов процедуры/функции с передачей параметров и получением результата
 finally
   FreeLibrary(Lib); // Выгрузка библиотеки
 end;
end;


PVOzerski   (2005-06-23 11:45:00) [33]

В общем виде, используют сочетание функций LoadLibrary и GetProcAddress применительно к процедурной переменной.


Страницы:   1 2

Наверх

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