Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 13.08.2008, 22:46
dmdx dmdx вне форума
Начинающий
 
Регистрация: 24.05.2008
Адрес: Москва
Сообщения: 133
Репутация: 15
По умолчанию Динамическая библиотека. Проблема загрузки.

Доброго всем настроения.
Народ помогите разораться в ошибке. Вроде как все правильно делаю.
вот исходники:

FunDll
Код:
library FunDll;

uses
  SysUtils,
  dialogs,
  Classes;

{$R *.res}

procedure ShowMessage(text: string); stdcall; export;
begin
 ShowMessage(text);
end;

function Summ(x: integer; y: integer):integer; stdcall; export;
begin
 result:=x+y;
end;


exports
ShowMessage,
Summ;

end. 

Prog
Код:
unit uProgMain;

interface

uses
  Windows, Messages, SysUtils,  Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TSumm = function (x: integer; y: integer ): integer;

  TShowMgs = procedure (text: string);

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);

  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
const
 s: string = 'Welcome';
var
 dllHandle:  THandle;
 ShowMsg: TShowMgs;
begin
 @ShowMsg:=nil;
 dllHandle:=LoadLibrary('FunDll.dll');
 if dllHandle=0 then
  exit;
 @ShowMsg:=GetProcAddress(dllHandle,'ShowMessage');
 if @ShowMsg = nil then
  exit;
 // здесь пробывал задавать явно текст т.е. ShowMsg('Welcome');
 ShowMsg(s);
 
 FreeLibrary(dllHandle);
end;

end.

procedure TForm1.Button2Click(Sender: TObject);
var
 dllHandle:  THandle;
 Sum: TSumm;
begin
 @Sum:=nil;
 dllHandle:=LoadLibrary('FunDll.dll');
 if dllHandle=0 then
  exit;
 @Sum:=GetProcAddress(dllHandle,'Summ');
 if @Summ = nil then
  exit;
 showmessage(inttostr(sum(4,6)));
 FreeLibrary(dllHandle);
end;

end.

выдает ошибку . Не могу понять в чем ошибка. по ходу ругается на переполнение Стека. Вроде все правильно делаю.
Изображения
Тип файла: jpg pic1.JPG (13.6 Кбайт, 9 просмотров)
Тип файла: jpg pic2.JPG (56.6 Кбайт, 8 просмотров)
__________________
Програмист приходит на стрельбище. Стреляет. Прапор смотрит на мешень и говорит
Прапор: вы не попали ни один раз.
Программист: Пули вылетели, проблемы у вас.
Ответить с цитированием
  #2  
Старый 14.08.2008, 01:49
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,096
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

В обеих функциях?

Если только в ShowMessage (или как там она), то надо и в прогу и в либу в uses добавть ShareMem. Только в этом случае тебе еще придется тащить за собой bormm.dll (что-то типа того).

Или перепиши на использование PChar.

Т.к. по коду все вроде правильно.
Ответить с цитированием
  #3  
Старый 14.08.2008, 10:58
dmdx dmdx вне форума
Начинающий
 
Регистрация: 24.05.2008
Адрес: Москва
Сообщения: 133
Репутация: 15
По умолчанию

да в обех функциях
__________________
Програмист приходит на стрельбище. Стреляет. Прапор смотрит на мешень и говорит
Прапор: вы не попали ни один раз.
Программист: Пули вылетели, проблемы у вас.
Ответить с цитированием
  #4  
Старый 14.08.2008, 12:10
Аватар для Thrasher
Thrasher Thrasher вне форума
Illuminati
 
Регистрация: 06.03.2008
Адрес: Крым, г. Симферополь
Сообщения: 348
Репутация: 8808
По умолчанию

Ну не так нужно делать!

Во-первых, нужно объявить нормально функции в секции exports:

Код:

exports
ShowMessage name 'ShowMessage', 
Summ name 'ShowMessage';

Во-вторых, правильное объявление должно быть:

Код:

type
  TSumm  =  function (x: integer; y: integer ): integer;stdcall;

  TShowMgs  =  procedure (text: string);stdcall; // Как в библиотеке объявлено так должно быть объявлено и в программе!!!


В-третьих правильный вызов:
Код:

procedure TForm1.Button2Click(Sender: TObject);
var
 dllHandle:  THandle;
 Sum: TSumm;
begin
 @Sum := nil;
 dllHandle := LoadLibrary(PChar('FunDll.dll'));
 if dllHandle < 32 then // Ошибок загрузки DLL 32 штуки!!
  exit;
 @Sum := GetProcAddress(dllHandle, PChar('Summ'));
 if @Summ  =  nil then
  exit;
 showmessage(inttostr(sum(4, 6)));
 FreeLibrary(dllHandle);
end;

__________________
Хорошо написанная программа не требует документации
ICQ 9-184-668.
Ответить с цитированием
  #5  
Старый 14.08.2008, 14:04
dmdx dmdx вне форума
Начинающий
 
Регистрация: 24.05.2008
Адрес: Москва
Сообщения: 133
Репутация: 15
По умолчанию

Цитата:
Сообщение от Thrasher
Ну не так нужно делать!

Во-первых, нужно объявить нормально функции в секции exports:

Код:

exports
ShowMessage name 'ShowMessage', 
Summ name 'ShowMessage';

Во-вторых, правильное объявление должно быть:

Код:

type
  TSumm  =  function (x: integer; y: integer ): integer;stdcall;

  TShowMgs  =  procedure (text: string);stdcall; // Как в библиотеке объявлено так должно быть объявлено и в программе!!!


В-третьих правильный вызов:
Код:

procedure TForm1.Button2Click(Sender: TObject);
var
 dllHandle:  THandle;
 Sum: TSumm;
begin
 @Sum := nil;
 dllHandle := LoadLibrary(PChar('FunDll.dll'));
 if dllHandle < 32 then // Ошибок загрузки DLL 32 штуки!!
  exit;
 @Sum := GetProcAddress(dllHandle, PChar('Summ'));
 if @Summ  =  nil then
  exit;
 showmessage(inttostr(sum(4, 6)));
 FreeLibrary(dllHandle);
end;


с функцией сложение получилось спасибо понял в чем была ошибка, а вот с процедурой отображения текста все таже ошибка, но я думаю тут уже ошибка моя где то в самой процедуре. Хотя если статически загружить все отлично работает. пробывал вот так в dll
Код:
procedure ShowMessage(text: pchar); stdcall; export;
begin
 ShowMessage(text);
end;
и в модуле соответственно менял
Код:
 TShowMgs  =  procedure (text: pchar);stdcall;
...
procedure TForm1.Button2Click(Sender: TObject);
var
 dllHandle: THandle;
 ShowMsg:TShowMgs;
begin
@ShowMsg:=nil;
dllHandle:=LoadLibrary(PChar('FunDll.dll'));
if dllHandle<32 then
 exit;
@ShowMsg:=GetProcAddress(dllHandle,Pchar('ShowMessage'));
if @ShowMsg=nil then
 exit;
ShowMsg(pchar('Welcome'));
FreeLibrary(dllHandle);
end;

все равно ошибка. буду думать.
__________________
Програмист приходит на стрельбище. Стреляет. Прапор смотрит на мешень и говорит
Прапор: вы не попали ни один раз.
Программист: Пули вылетели, проблемы у вас.
Ответить с цитированием
  #6  
Старый 14.08.2008, 18:48
Аватар для moo2k
moo2k moo2k вне форума
Активный
 
Регистрация: 05.12.2006
Адрес: где-то там...
Сообщения: 321
Репутация: 35
По умолчанию

В чем ошибка? Покажи скрин. Или попробуй конвертни PChar в String с помощью StrPas.
__________________
Программирование - это искусство и наш смысл жизни.
Ответить с цитированием
  #7  
Старый 14.08.2008, 22:22
dmdx dmdx вне форума
Начинающий
 
Регистрация: 24.05.2008
Адрес: Москва
Сообщения: 133
Репутация: 15
По умолчанию

УРРААААААААААААА Все получилось. Загрузка удалась.
dll code
Код:
library FunDll;

uses
  SysUtils,
  dialogs,
  Classes;

{$R *.res}

procedure ShowMsg(text: pchar); stdcall; export;
begin
 ShowMessage(text);
end;

function Summ(x: integer; y: integer):integer; stdcall; export;
begin
 result:=x+y;
end;


exports
ShowMsg name 'ShowMsg',
Summ name 'Summ';

begin
end.

prog code
Код:
unit uProgMain;

interface

uses
  Windows, Messages, SysUtils,  Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TSumm = function (x: integer; y: integer ): integer; stdcall;
  TShowMgs = procedure (text: pchar); stdcall;
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);

  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
const
 s: string = 'Welcome';
var
 dllHandle:  THandle;
 ShowMsg: TShowMgs;
begin
 @ShowMsg:=nil;
 dllHandle:=LoadLibrary(pchar('FunDll.dll'));
 if dllHandle=0 then
  exit;
 @ShowMsg:=GetProcAddress(dllHandle,'ShowMsg');
 if @ShowMsg = nil then
  exit;
 ShowMsg(pchar(s));
 @ShowMsg:=nil;
 FreeLibrary(dllHandle);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
 dllHandle: THandle;
 Suma: TSumm;
begin
 @Suma:=nil;
 dllHandle:=LoadLibrary(pchar('FunDll.dll'));
 if dllHandle<32 then
  exit;
 @Suma:=GetProcAddress(dllHandle,PChar('Summ'));
 if @Suma=nil then
  exit;
 ShowMessage(inttostr(Suma(2,5)));
 @Suma:=nil;
 FreeLibrary(dllHandle);
end;

end.

ВСЕМ КТО ПРИНИМАЛ УЧАСТИЕ ОГРОМНЕЙШЕЕ СПАСИБО НАРОД!!!

Вот только у меня есть один вопрос, а точнее уточнение.

в dll когда пишешь процу или функцию указываешь типа export, я так понимаю это типа клочевого слова для экспорта
procedure ShowMsg(Text: PChar); stdcall export
Ни где не могу найти толкового описания этой переменной в процах или функциях. Т.к. в разных книгах и описаниях то присутствует этот экспорт, а у некоторых отсутствует.
__________________
Програмист приходит на стрельбище. Стреляет. Прапор смотрит на мешень и говорит
Прапор: вы не попали ни один раз.
Программист: Пули вылетели, проблемы у вас.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 08:38.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025