Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2003.07.10;
Скачать: [xml.tar.bz2];

Вниз

Экспорт функции из 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.015 c
1-31261
Behemoth
2003-06-26 10:06
2003.07.10
Поможите с модальными формами...


3-31154
lutikh
2003-06-18 22:43
2003.07.10
Access и dbf-таблицы


3-31102
SSAlex
2003-06-17 13:22
2003.07.10
Доступ до данных в форме Access.


1-31325
hex_for_delphi
2003-06-26 17:20
2003.07.10
как сделать цикл шагами


1-31329
Um
2003-06-25 06:44
2003.07.10
inherited inherited;





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский