Создать dll файл и использовать его

kurljuta

Всем привет. Задача заключается вот в чем:а) Написать динамическую библиотеку, содержащую процедуру, которая создает новую форму, в заголовке формы выводит число N, а на форме - результат вычислений.б) Написать программу, использующую созданную библиотеку и вызывающую процедуру с некоторым значением N. Задание: Количество делителей числа.Перерыл кучу форумов и сайтов, в итоге с созданием dll запутался вообще( Нашел, что структура dll такова:
library mydll;
 
uses SysUtils, Classes;
 
{Определяем функцию как stdcall}
function GetSimpleText(LangRus: Boolean): PChar; stdcall;
begin
   {В зависимости от LangRus возвращаем русскую (True) либо английскую (False) фразу}
   if LangRus then
     Result := PChar('Здравствуй, мир!')
   else
     Result := PChar('Hello, world!');
end;
 
{Директива exports указывает, какие функции будут экспортированы этой DLL}
exports GetSimpleText;
 
begin
end.
Создаю, в итоге не компилируется в dll (надо ли?)... Разъясните, может чем поможете.
14 ответов

kurljuta

Этот код как и должно быть нормально компилируется.


kurljuta

angstrom, а вот как я делаю, так надо?Создаю dll (File -> New -> Other -> DLL Wizard). Далее кидаю этот текст туда и сохраняю его под именем mydll.dpr, так? Или как-то надо скомпилировать в mydll.dll (как, если да?)А затем подскажите, что должно быть на форме Form1 написано, чтобы вызвать mydll.dll на исполнение? Запутался...


kurljuta

Всё правильно создал теперь возможный код программы. И не забудь разместить DLL в папку с проектом.
unit Unit41;
 
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;
 
function GetSimpleText(LangRus: Boolean): PChar; stdcall; external 'mydll.dll';
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
procedure TForm1.Button1Click(Sender: TObject);
var
  hDLL : THandle;
begin
  hDLL := LoadLibrary(PChar('mydll.dll'));
  if hDLL = 0 then
    Exit;
 
  MessageBox(Handle, GetSimpleText(True), '', MB_OK);
 
  if hDll <> 0 then
    FreeLibrary(hDLL);
end;
 
end.


kurljuta

Создаешь dll и сохраняешь проект (при попытке запустить dll у тебя выдает ошибка?=)) но она у тебя в папке с проектом появится. Далее создаешь свой проект и вот код:
unit Unit1;
 
interface
 
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
 
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
function GetSimpleText(LangRus: Boolean): PChar; stdcall; external 'MYDLL.DLL';
 
{$R *.dfm}
 
procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowMessage(StrPas(GetSimpleText(True)));
  ShowMessage(StrPas(GetSimpleText(False)));
end;
 
end.
Сохраняешь, компилируешь (запускаешь) и в папке с проектом появится твоя программа туда свою dll скопируй (только переименуй в mydll вот и все=)).


kurljuta

Создал dll. Так получилось (для моей задачи)?
library mydll;
 
uses
  SysUtils,
  Classes;
 
function NOD(k, i, n: integer): integer; stdcall;
begin
  n:=StrtoInt(Form1.Edit1.Text);
  k:=0;
  for i:=0 to n do
  if n mod i = 0 then
  begin
    inc(k);
  end;
  Form1.Caption:='×èñëî: ' + Edit1.Text;
  Form1.Label1.Caption:=inttostr(k);
end;
 
exports Nod;
 
begin
end.


kurljuta

У тебя в DLL используются строки, при этом в uses рекомендуется подключить ShareMem. Далее идёт попытка использовать Form1. DLL-ка ничего о ней не знает. Верни как задумано число, а все изменения на форме проводи в вызывающей программе.


kurljuta

angstrom, дак у меня:Написать динамическую библиотеку, содержащую процедуру, которая создает новую форму, в заголовке формы выводит число N, а на форме - результат вычислений.То есть записывать число в название формы и выводить ответ на форму должна сама DLL


kurljuta

Ну так и создавай форму внутри DLL, а выхода на внешнюю у тебя в данном случае нет.
var
  Form : TForm;
begin
  Form := TForm.Create(NIL);
...


kurljuta

angstrom, не получается, видимо не так понимаю((
library mydll;
 
uses
  SysUtils,
  Classes;
  ShareMem;
 
var
  Form : TForm;
 
function NOD(k, i, n: integer): integer; stdcall;
begin
  Form := TForm.Create(NIL);
  k:=0;
  for i:=0 to n do
  if n mod i = 0 then
  begin
    inc(k);
  end;
  Form1.Caption:='×èñëî: ' + Edit1.Text;
  Form1.Label1.Caption:=inttostr(k);
end;
 
exports Nod;
 
begin
end.
Ругается и на модель и на создание формы..и с таким кодом при компилировании dll ошибка выходит, не компилируется


kurljuta

Или я что то не догоняю, или ты что то намудрил): Откуда Form1?) Если у тебя:
Form : TForm;
Откуда ты пытаешься взять это число:
Form1.Caption:='Число: ' + Edit1.Text;
function NOD(k, i, n: integer; FormCaption: String): integer; stdcall;
begin
  Form := TForm.Create(NIL);
  k:=0;
  for i:=0 to n do
  if n mod i = 0 then
  begin
    inc(k);
  end;
  Form.Caption:='Число: ' + FormCaption;
end;


kurljuta

Hennasy, я даже не намудрил) я просто понять смысла не могу, как и что куда вставлять... мы должны в dll прописать, что должна создаться форма новая, на которой в названии выведется число n а на форме самой ответ. Как это сделать? В var прописываю Form: TForm; в итоге ругается, на модель тоже ругается...


kurljuta

И какой Label на новой форме? Откуда?)


kurljuta

Hennasy, это число должно браться из Edit'а как раз, на сколько я понимаю. Мы должны в программе своей вводить число n, нажать кнопку и должен по ней вызваться Dll файл (а в самом деле в процедуре уже прописано, что вызывается новая форма с тем что я написал...) как то так)


kurljuta

Ну:
function NOD(k, i, n: integer; FormCaption: String): integer; stdcall;
begin
  Form := TForm.Create(NIL);
  k:=0;
  for i:=0 to n do
  if n mod i = 0 then
  begin
    inc(k);
  end;
  Form.Caption:='Число: ' + FormCaption;
end;
А уже в своей программе передаешь то что у тебя написано в Edit1 т.е. вызываешь функцию: NOD(k, i, n, Edit1.Text,) - передавая тем самым k i n и текст из Edit'a.