Форум: "Начинающим";
Текущий архив: 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.054 c