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

Вниз

Подскажите пример исходника программы работающей с dll ?   Найти похожие ветки 

 
Not   (2006-09-13 04:21) [0]

Нужно, чтобы программа могла работать с dllками.
Программа вызывает dll - Dll - может вызывать некие нужные ей функции программы - и под конец возвращает результат своей работы.

Как такое можно организовать ?
Если можно, дайте исходники примеров такой программы и Dll ?


 
Elen ©   (2006-09-13 08:19) [1]

Привет Not
Вот те ДЛЛка

library Project2;

{ Important note about DLL memory management: ShareMem must be the
 first unit in your library"s USES clause AND your project"s (select
 Project-View Source) USES clause if your DLL exports any procedures or
 functions that pass strings as parameters or function results. This
 applies to all strings passed to and from your DLL--even those that
 are nested in records and classes. ShareMem is the interface unit to
 the BORLNDMM.DLL shared memory manager, which must be deployed along
 with your DLL. To avoid using BORLNDMM.DLL, pass string information
 using PChar or ShortString parameters. }

uses
 SysUtils,
 Classes;

{$R *.res}

//********** FUNCTION **********
function BlaBla(s:integer):integer;
begin
result:=s+s;
end;
//********** END FUNCTION ******

exports BlaBla;
begin
end.


А вот работа с ней (статик вызов)

unit Unit1;

interface

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

type
 TForm1 = class(TForm)
   procedure FormCreate(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;
  function BlaBla(s:integer):integer; external "project2.dll";
var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
caption:=inttostr(blabla(5));
end;

end.


И Иди рулить мануалы по DLL


 
Not   (2006-09-14 03:22) [2]

2 Elen.
Спасибо за пример !

А как загрузить динамически? Делаю так:


type
 TRegi = record
    InterfaceType : Integer;
    Version       : Integer;
 end;

procedure TForm1.Button1Click(Sender: TObject);
var
 InfoA2     : TRegi;
 GetInfo1  : function : TRegi;
 LibHandle : THandle;
begin
   @GetInfo1 := nil;
   LibHandle := LoadLibrary("Test1.dll");
   if LibHandle >= 32 then begin
     @GetInfo1 := GetProcAddress(LibHandle, "GetInfo1");
     if @GetInfo1 <> nil then begin
       InfoA2 := GetInfo1;
       s1 := IntToStr(InfoA2.Version);
       ShowMessage(s1);
     end;
   end;
   FreeLibrary(LibHandle);
end;



Но вместо числа 1 в Version я получаю билиберду. В чём тут ошибка ?

Функция в Dll выглядит так :

function GetInfo1: TRegi; stdcall;
begin
 Result.InterfaceType := 1;
 Result.Version       := 1;
 beep;
end;


Объявляю её так :


exports
 GetInfo1;


 
Not   (2006-09-14 03:27) [3]

И ещё вопрос.

Мне надо передать в DLL следующие данные:

type
 TVector3f = array [0..2] of Single;

       TFGTData = record
         PTInd  : array [0..2] of Integer;
         TXInd  : array [0..2] of Integer;
         Enable : Boolean;
         NRData : Integer;
       end;

     TFData = record
       FGTData      : array of TFGTData;
       Name         : string;
       MName        : string;
       Visible      : Boolean;
       NTData       : Byte;
     end;

   TFDatas = array of TFData;

   TTXData = record
     X, Y    : Single;
     Enabled : Boolean;
   end;

   TPData = record
     ITData  : TVector3f;
     Enabled : Boolean;
     BNData  : SmallInt;
   end;

 TMData = record
   Name     : string;
   PData    : array of TPData;
   TXData   : array of TTXData;
   FData    : TFDatas;
   Visible  : Boolean;
 end;

 TMDatas = array of TMData;

var
 MDatas1 : TMDatas;


Передать нужно MDatas1, чтобы в DLL их можно было редактировать. Как такое лучше организовать ?

Тут dll - это типа плагин, который может таким образом изменять данные программы.


 
Джо ©   (2006-09-14 03:34) [4]

> [2] Not   (14.09.06 03:22)
> А как загрузить динамически? Делаю так:


Делай так:
var
 GetInfo1  : function : TRegi; stdcall;


 
Elen ©   (2006-09-14 08:10) [5]


> Мне надо передать в DLL следующие данные:

ИМХО лучше указателем.


 
Not   (2006-09-15 01:14) [6]

Джо
Спасибо.


> Elen ©   (14.09.06 08:10) [5]
> > Мне надо передать в DLL следующие данные:
>
> ИМХО лучше указателем.

А как именно ? Можно пример ?


 
Zeqfreed ©   (2006-09-15 01:17) [7]

Перед передачей данных типа String между приложением и библиотекой следует очень внимательно прочитать комментарий, обозначенный в шаблоне библиотеки, генерируемом средой.


 
Not   (2006-09-15 01:32) [8]

Непонял. Какой комментарий?
Можно пример ?


 
Zeqfreed ©   (2006-09-15 01:33) [9]

> [6] Not   (15.09.06 01:14)


> А как именно ? Можно пример ?

SharedTypes.pas:

unit SharedTypes;

interface

type
 PMyStruct = ^TMyStruct;
 TMyStruct = record
  a,b,c : Integer;
 end;

implementation

end.


Main.pas:

uses
 …, SharedTypes, …;

. . .

procedure TForm1.Button1Click(Sender: TObject);
type
 TModifyMyStructProc = procedure(Struct : PMyStruct);
var
 h : THandle;
 Proc : TModifyMyStructProc;
 Struct : TMyStruct;
begin
 with Struct do begin
  a := 5;
  b := 5;
  c := 5;
 end;

 h := LoadLibrary("../lib/lib.dll");
 if (h <> 0) then begin
  Proc := GetProcAddress(h, "ModifyMyStruct");
  if (@Proc <> nil) then Proc(PMyStruct(@Struct));

  FreeLibrary(h);
 end;

 with Struct do
  ShowMessageFmt("Modified struct: %d %d %d", [a, b, c]);
end;


lib.dpr:

library lib;

uses
 Windows,
 SharedTypes in "..\SharedTypes.pas";

procedure  ModifyMyStruct(Struct : PMyStruct);
begin
 with Struct^ do begin
  a := a + 1;
  b := b + 2;
  c := c - 1;  
 end;
end;

exports
ModifyMyStruct;

begin
end.


Что-то типа такого :)


 
Zeqfreed ©   (2006-09-15 01:34) [10]

> [8] Not   (15.09.06 01:32)


> Какой комментарий?

Вот этот:

{ Important note about DLL memory management: ShareMem must be the
first unit in your library"s USES clause AND your project"s (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }


 
Not   (2006-09-16 01:11) [11]


> Zeqfreed ©   (15.09.06 01:33) [9]

Но здесь же передаётся просто record. А мне нужно рекорд с динамическими массивами. Или это всё равно?


> Zeqfreed ©   (15.09.06 01:34) [10]

А как это перевести?


 
Zeqfreed ©   (2006-09-16 01:17) [12]

> [11] Not   (16.09.06 01:11)


> Но здесь же передаётся просто record. А мне нужно рекорд
> с динамическими массивами. Или это всё равно?

Ну если не делать ничего предосудительного, тогда можно и динамические массивы использовать.


> А как это перевести?

Если хочешь передавать длинные строки, то надо добавить ShareMem первым модулем в списке uses, как в приложении, так и в библиотеке.


 
Германн ©   (2006-09-16 01:30) [13]


> Если хочешь передавать длинные строки, то надо добавить
> ShareMem первым модулем в списке uses, как в приложении,
>  так и в библиотеке.
>

И динамические массивы тоже подпадают в ту же категорию.


 
Zeqfreed ©   (2006-09-16 01:40) [14]

> [13] Германн ©   (16.09.06 01:30)

Если быть аккуратным, то можно работать с динамическими массивами, да и строками в принципе без ShareMem :)


 
Not   (2006-09-16 01:47) [15]


> Zeqfreed ©   (16.09.06 01:17) [12]
> > А как это перевести?
>
> Если хочешь передавать длинные строки, то надо добавить
> ShareMem первым модулем в списке uses, как в приложении,
>  так и в библиотеке.

Спасибо.


> Ну если не делать ничего предосудительного, тогда можно
> и динамические массивы использовать.

А если из dll менять разменость массива, то это ничего?

И ещё, с этим можно будет работать из Си?


 
Zeqfreed ©   (2006-09-16 01:51) [16]

> [15] Not   (16.09.06 01:47)


> А если из dll менять разменость массива, то это ничего?

Зависит от ситуации. Я бы все-таки не советовал пренебрегать предупреждением разработчиков и подключил таки ShareMem. Но если необходимо работать с библиотекой из Си, то о Ansi-строках и динамических массивах придется забыть :)


 
Германн ©   (2006-09-16 02:02) [17]


> Zeqfreed ©   (16.09.06 01:40) [14]
>
> > [13] Германн ©   (16.09.06 01:30)
>
> Если быть аккуратным, то можно работать с динамическими
> массивами, да и строками в принципе без ShareMem :)

"Если быть аккуратным" это как это? Мыть руки перед работой с данными типами? :-)
Имхо, есть в дельфи типы с "управляемым временем жизни". И если они есть, то ведь должен же быть кто-то, кто будет управлять!


 
Zeqfreed ©   (2006-09-16 02:10) [18]

> [17] Германн ©   (16.09.06 02:02)



> И если они есть, то ведь должен же быть кто-то, кто будет
> управлять!

Ну да, там будет даже два «управляльщика». И именно потому что они не подозревают друг о друге, при некоторых операциях может случиться «бяка». Но, например, операции чтения/записи можно проводить вполне безопасно.


 
Германн ©   (2006-09-16 02:22) [19]


> Ну да, там будет даже два «управляльщика». И именно потому
> что они не подозревают друг о друге, при некоторых операциях
> может случиться «бяка». Но, например, операции чтения/записи
> можно проводить вполне безопасно.
>

Ну да. Как раз сей совет "очень подходит для конференции Начинающие"! :-((

С [16] согласен. Но и ещё раз! В dll лучше использовать "родные" типы. Т.е. PChar.


 
Not   (2006-09-16 02:22) [20]

А как мне тогда быть то?
Мне надо, чтобы на любом языке плагины писать можно было бы.


 
Zeqfreed ©   (2006-09-16 02:25) [21]

> [20] Not   (16.09.06 02:22)

Учимся активно испльзовать указатели и динамическое распределение памяти aka GetMem/FreeMem, StrAlloc/StrDispose, GlobalAlloc/GlobalFree. Хотя я обычно ограничиваюсь первой парой.


 
Германн ©   (2006-09-16 02:40) [22]


> Not   (16.09.06 02:22) [20]
>
> А как мне тогда быть то?
> Мне надо, чтобы на любом языке плагины писать можно было
> бы.
> <Цитата>
>
> Zeqfreed ©   (16.09.06 02:25) [21]
>
> > [20] Not   (16.09.06 02:22)
>
> Учимся активно испльзовать указатели и динамическое распределение
> памяти aka GetMem/FreeMem, StrAlloc/StrDispose, GlobalAlloc/GlobalFree.
>

Именно так!


 
Not   (2006-09-16 03:08) [23]

А через потоки это можно делать одновременно и в Си и в Дельфи?


 
Zeqfreed ©   (2006-09-16 03:12) [24]

> [23] Not   (16.09.06 03:08)


> А через потоки это можно делать одновременно и в Си и в
> Дельфи?

Делать что? Одновременно получится только на дву- и более ядерном процессоре :)

Что ты собираешься делать в потоках то? И, главное, зачем?


 
Германн ©   (2006-09-16 03:21) [25]

Я, пожалуй, пойду спать. Потоки, процессоры многоядерные, имхо - перебор.


 
Not   (2006-09-16 03:50) [26]

Имею в виду Stream, а не Thread.


 
Zeqfreed ©   (2006-09-16 09:17) [27]

> [26] Not   (16.09.06 03:50)

Разумеется, в Си нет TStream, тем более Си знать ничего не знает о классах Delphi. Так что нельзя.



Страницы: 1 вся ветка

Форум: "Начинающим";
Текущий архив: 2006.10.08;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.52 MB
Время: 0.035 c
15-1158600999
Весь в делах
2006-09-18 21:36
2006.10.08
Фашисты опять лезут власть


15-1157075691
Доктор Шмурге
2006-09-01 05:54
2006.10.08
Куда попадет Сатана после смерти?


3-1155125919
DelphiLexx
2006-08-09 16:18
2006.10.08
TFIBDataSet получить следующее значение поля в OnDrawColumnCell


3-1155189999
Stanislav
2006-08-10 10:06
2006.10.08
Размер содержимого Blob поля


11-1133818651
Vedun
2005-12-06 00:37
2006.10.08
Работа с базами данных





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский