Текущий архив: 2003.07.10;
Скачать: CL | DM;
Вниз
Экспорт функции из DLL Найти похожие ветки
← →
Эдуард (2003-06-21 23:52) [0]Непонятная проблема возникла.
Уважаемые надеюсь на вашу помощь.
Значит есть DLL с процедурой такой:
type
PInteger = ^Integer;
procedure MyProc(P: PInteger); stdcall;
begin
{Заведомо известно, что P это указатель на тип Integer}
P^ := P^ + I;
end;
Вобщем-то хватит.
В коде программы описан тотже тип PInteger и в одной из процедур написано так:
var
P: Integer;
begin
P := 7;
MyProc(@P);
....
теперь главная проблема
если я экспортирую процедуру из DLL статически то она работает
procedure MyProc(P: PInteger); stdcall; external "mydll.dll";
а если динамически, через LoadLibrary, то указатель не передается и соответственно не возвращается.
В чем щдесь грабли???
← →
DrPass (2003-06-22 00:06) [1]А в прототипе ты не забыл stdcall написать?
← →
jack128 (2003-06-22 01:09) [2]
> если динамически, через LoadLibrary, то указатель не передается
>
В смысле GetProcAddress возвращает NULL??
Код в студию
← →
Эдуард (2003-06-22 22:02) [3]не много не поняли меня наверное, в параметры функции (в данном случае MyProc) передается указатель на объект типа INteger, так вот именно он и не передается :) (простите за тофтологию). А если делать не через LoadLibrary то все ОК.
2DrPAss: stdcall писал везде где надо, а точнее там везде надо. Объясните, что значит в прототипе?
← →
sniknik (2003-06-22 22:13) [4]Эдуард (22.06.03 22:02)
> Объясните, что значит в прототипе?
в программе в описании.
Вобщем-то хватит. ;о)) (а лутше бы показал как оно у тебя описано/вызывается, уже бы сказали где напортачил)
← →
jack128 (2003-06-22 23:04) [5]
> Объясните, что значит в прототипе?
Посмотри Windows.pas. То что написано про CreateFile, например, в interface - это прототип. А то что в implementation это реализация.
← →
DrPass (2003-06-22 23:37) [6]
> stdcall писал везде где надо, а точнее там везде надо
Ну, чтобы не забивать голову фигней, убери его везде, где написал (и в библиотеке, и в проге). Должно заработать
← →
Эдуард (2003-06-23 12:57) [7]Объясните мне неучу, зачем stdcall нужен?
щас код выложу
← →
Skier (2003-06-23 12:59) [8]>Эдуард (23.06.03 12:57)
> Объясните мне неучу, зачем stdcall нужен?
F1 + stdcall. Делов-то...
← →
Эдуард (2003-06-23 13:24) [9]F1 + stdcall? я читал, и есть подозрения что не понял т.к. английский все-таки наверное я в нем не силен :)
пишу код:
значит код Dll"ки
library pack;
uses
SysUtils,
Classes, Types;
type
TBytes = array [0..311] of Byte;
PBytes = ^TBytes;
procedure Shuffle(FCards: PBytes); stdcall;
var
Cards: TBytes;
i, j, rnd_pos, pack_pos: Integer;
begin
randomize;
for i:=0 to 311 do
Cards [i] := 255;
for i:=0 to 311 do
begin
rnd_pos := Random (312 - i);
j := -1;
pack_pos := -1;
repeat
Inc(pack_pos);
if Cards[pack_pos] = 255 then
Inc(j);
until rnd_pos = j;
Cards[pack_pos] := FCards^[i];
end;
FCards^ := Cards;
end;
exports Shuffle;
begin
end.
теперь вызов из программы:
короче:
var
Cards: TBytes; {описанный в DLL"ке. естесно в проге тоже тип описан}
Dll: THandle;
ShuffleProc: procedure (FCards: PBytes);
begin
@ShuffleProc := nil;
{Пытаемся загрузить библиотеку}
Dll:= LoadLibrary("MYDLL.DLL");
{Если все OK}
if Dll>= 32 then begin
{...то пытаемся получить адрес функции в библиотеке}
@ShuffleProc := GetProcAddress(Dll,"Shuffle");
{Если и здесь все OK}
if @ShuffleProc <> nil then
{...то вызываем эту функцию и показываем результат}
ShuffleProc(@Cards); {Здесь не работает}
end;
{И не забываем освободить память и выгрузить DLL}
FreeLibrary(Dll);
end;
вот собственно и все, указатель на Cards ен передается и в Dll вызывается Access Violetion (извините если не правильно написал), вообщем обращение к несуществующему участку памяти.
← →
Skier (2003-06-23 13:51) [10]type
TShuffleProc = procedure (FCards: PBytes); stdcall;
var
Cards: TBytes; {описанный в DLL"ке. естесно в проге тоже тип описан}
Dll: THandle;
ShuffleProc: TShuffleProc;
begin
@ShuffleProc := nil;
{Пытаемся загрузить библиотеку}
Dll:= LoadLibrary("MYDLL.DLL");
try
{Если все OK}
if Dll>= 32 then begin
{...то пытаемся получить адрес функции в библиотеке}
@ShuffleProc := GetProcAddress(Dll,"Shuffle");
{Если и здесь все OK}
if @ShuffleProc <> nil then
{...то вызываем эту функцию и показываем результат}
ShuffleProc(@Cards); {Здесь не работает}
end;
{И не забываем освободить память и выгрузить DLL}
finally
FreeLibrary(Dll);
end; //try
end;
← →
Эдуард (2003-06-23 20:49) [11]TShuffleProc = procedure (FCards: PBytes); stdcall; вот про это забыл написать тут, но не в этом дело. Не передается указатель на объект Cards.
← →
jack128 (2003-06-23 23:12) [12]
> Объясните мне неучу, зачем stdcall нужен?
Модель передачи параметров в функцию. Параметры передаются через стек или регистры процессора - это и определяет модель вызова.
stdcall - модель для апи windows
register - по умолчанию для функций Delphi
cdecl - C++
и т.д.
← →
Эдуард (2003-06-24 03:49) [13]Так с stdcall все понятно, а вот с моей проблемой ничего не понятно, уважаемые где тут грабли то?
← →
Babay (2003-06-25 05:29) [14]Я вот так сделал и все работает (Накопировал твой код и создал прогу и длл ничего почти не правил кроме того что тебе Skier указал)
ДЛЛ (полная копия)
library pack;
uses
SysUtils,
Classes, Types;
type
TBytes = array [0..311] of Byte;
PBytes = ^TBytes;
procedure Shuffle(FCards: PBytes); stdcall;
var
Cards: TBytes;
i, j, rnd_pos, pack_pos: Integer;
begin
randomize;
for i:=0 to 311 do
Cards [i] := 255;
for i:=0 to 311 do
begin
rnd_pos := Random (312 - i);
j := -1;
pack_pos := -1;
repeat
Inc(pack_pos);
if Cards[pack_pos] = 255 then
Inc(j);
until rnd_pos = j;
Cards[pack_pos] := FCards^[i];
end;
FCards^ := Cards;
end;
exports Shuffle;
begin
end.
Прога
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
type
TBytes = array [0..311] of Byte;
PBytes = ^TBytes;
procedure TForm1.Button1Click(Sender: TObject);
type
TShuffleProc = procedure (FCards: PBytes); stdcall;
var
Cards: TBytes;
Dll: THandle;
ShuffleProc: TShuffleProc;
begin
@ShuffleProc := nil;
Dll:= LoadLibrary("Pack.DLL");
if Dll>= 32 then begin
@ShuffleProc := GetProcAddress(Dll,"Shuffle");
if @ShuffleProc <> nil then
ShuffleProc(@Cards); end;
FreeLibrary(Dll);
Caption:=InttoStr(cards[3]);// это просто проверка что чегото происходит
end;
end.
вот так у меня все работает сравни со соим ты гдето что то упустил наверное
← →
Эдуард (2003-06-27 17:21) [15]полностью скопировал твой код, неработает!!!! Я только в проге добавил чтоб массив cards заполнялся 0, и он после процедуры ShuffleProc таким же и остается. Мож у меня с компом че не так?
← →
Эдуард (2003-06-27 17:36) [16]УРА!!!!! Вродже работает, всем спасибо!!!!
Страницы: 1 вся ветка
Текущий архив: 2003.07.10;
Скачать: CL | DM;
Память: 0.49 MB
Время: 0.008 c