![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
вызов DLL [D7, WinXP]
Цукор 5 © (2005-09-11 13:08:00)Есть библиотека :
library Project1;
uses
SysUtils,
Classes;
type MyRetVal=record
Line1:PChar;
Line2:PChar;
Dept :Byte;
Group:Byte;
end;
type TVal=array of MyRetVal;
function ReadSales(Num1,Num2:Word; var Value:TVal):Boolean;stdcall;
var I:Integer;
begin
SetLength(Value,5);
for I:=0 to Length(Value)-1 do
begin
Value[I].Line1:=PChar('Test1');
Value[I].Line2:=PChar('Test2');
Value[I].Dept :=$01;
Value[I].Group:=$0a;
end;
Result:=True;
end;
Exports
ReadSales;
{$R *.res}
begin
end.
Вызываю так :
procedure TForm1.Button1Click(Sender: TObject);
var hDLL:HWND;
Val:TVal;
I:Integer;
ReadSales:function(Num1,Num2:Word;var Value:TVal):boolean;stdcall;
begin
hDLL := LoadLibrary ('Project1');
if hDLL<>0 then
begin
@ReadSales:=GetProcAddress(hDLL,'ReadSales');
if Assigned(@ReadSales) then
ReadSales(1,5,Val);
for I:=0 to Length(Val)-1 do
begin
Memo1.Lines.Add('L'+IntToStr(I)+'_'+Val[I].Line1);
Memo1.Lines.Add('L'+IntToStr(I)+'_'+Val[I].Line2);
end;
// до это момента все прекрасно !
FreeLibrary (hDLL);// а вот тут AV
end
else MessageDlg('Error!!!',mtError,[MbOk],0);
end;
Не могу понять в чем причина. Я уже и SetLength(Val,0) и Val=nil делал...не то :(
P.S. Да простят меня модераторы... я не знаю как назвать тему вопроса.
Slym (2005-09-13 09:36:00) [1]
type
PEntry=^TEntry;
TEntry=packed record
Line1:PChar;
Line2:PChar;
Dept :Byte;
Group:Byte;
end;
PEntries=^TEntries;
TEntries=array[0..MaxListSize - 1] of PEntry;
PEntryArray=^TEntryArray;
TEntryArray=packed record
Size:integer;
Entries:PEntries;
end;
function OpenDevice:PEntryArray;stdcall;
begin
New(result);
result.Size:=0;
result.Entries:=nil;
end;
function ClearEntryArray(Dev:PEntryArray):LongBool;stdcall;
var i:integer;
Entry:PEntry;
begin
for i:=0 to Dev.Size-1 do
begin
Entry:=Dev.Entries[i];
if Entry.Line1<>nil then
FreeMem(Entry.Line1);
if Entry.Line2<>nil then
FreeMem(Entry.Line2);
Dispose(Entry);
end;
FreeMem(Dev.Entries);
Dev.Size:=0;
end;
function CloseDevice(Dev:PEntryArray):LongBool;stdcall;
begin
ClearEntryArray(Dev);
Dispose(Dev);
end;
const Line='Test,Test';
function ReadDevice(Dev:PEntryArray):LongBool;stdcall;
var
i:integer;
Entry:PEntry;
begin
if Dev.Size>0 then
ClearEntryArray(Dev);
Dev.Size:=10;
GetMem(Dev.Entries,SizeOf(PEntry)*Dev.Size);
for i:=0 to Dev.Size-1 do
begin
New(Dev.Entries[i]);
Entry:=Dev.Entries[i];
GetMem(Entry.Line1,Length(Line)+1);
StrLCopy(Entry.Line1,PChar(Line),Length(Line));
GetMem(Entry.Line2,Length(Line)+1);
StrLCopy(Entry.Line2,PChar(Line),Length(Line));
Entry.Dept:=i;
Entry.Group:=Dev.Size-i;
end;
end;
procedure Usage;
var EntryArray:PEntryArray;
i:integer;
begin
EntryArray:=OpenDevice;
ReadDevice(EntryArray);
for i:=0 to EntryArray.Size-1 do
begin
MessageBox(0,EntryArray.Entries[i].Line1,EntryArray.Entries[i].Line2,0);
end;
CloseDevice(EntryArray);
end;
Defunct (2005-09-13 02:23:00) [2]> Цукор 5
В [33] я отвечал на [30].
чтобы развеять сомнения относительно достоверности, привожу аналог структуры
TMyRetVal=record
Line1:String[31];
Line2:String[31];
Dept : Byte;
end;
на Cи:
typedef SmallString<31> MyStr;
struct TMyRetVal
{
MyStr Line1;
MyStr Line2;
char Dept;
};
Defunct (2005-09-13 02:06:00) [3]> в Delphi будет легче работать со String
читать так:
в Delphi будет легче работать со String[] чем с array[] of char.
Defunct (2005-09-13 02:00:00) [4]Цукор 5 (13.09.05 01:49) [35]
Герман имел в виду, помоему то же самое.
String[..] это уже и так array[..] of char.
> Меняю все на array[] of char.
не стоит, в Delphi будет легче работать со String, в других языках объявят за вас.
Цукор 5 (2005-09-13 01:49:00) [5]Блин. [33]<>[32]. Так где же истина???
Цукор 5 (2005-09-13 01:47:00) [6]2 Германн © (13.09.05 01:42) [32]
Понял. Меняю все на array[] of char.Надежней будет(наверное:О )
Спасибо!
Defunct (2005-09-13 01:46:00) [7]обязательно поставьте packedrecord
> А во всех ли языках есть String[25]?
String[25] это просто массив Char (array[0..25] of char), у которого первый символ содержит количество используемых символов массива. Объявить такой массив можно imho во всех языках.
ps: может быть лучше String[ 31]? (по 32 байта на строку, как-то более цивильно будет, заодно все поля будут выровняны на границу dword)
Германн (2005-09-13 01:42:00) [8]2 Цукор 5 (13.09.05 01:29) [30]
Имхо, String[] - есть Pascal'ева конструкция. И её НЕТ в других языках!
Но array[] of char - найдется везде, имхо.
А PChar - найдется во всех, наиболее известных языках и компиляторах, которые работают в среде Win32. Имхо!
Цукор 5 (2005-09-13 01:40:00) [9]Понятно,что для решения [27] структура ДОЛЖНА быть такой:
type
TMyRetVal=record
Line1:PChar;
Line2:PChar;
Dept : Byte;
end;
я вот думаю про http://www.delphimaster.ru/cgi-bin/forum.pl?id=1126539754&n=0.Там то нельзя указать Pchar ибо тогда я никогда не узнаю размер "массива"
З.Ы. Да простят меня модераторы за 2 вопроса в одной ветке.
Цукор 5 (2005-09-13 01:29:00) [10]2 Defunct © (13.09.05 01:17) [29]
Кстати,а еще вопросик. Вопрос навеян тем,что библиотека будет передана не Delphi-программистам.
Вот я обьявил такую структуру :
type
TMyRetVal=record
Line1:String[25];
Line2:String[25];
Dept : Byte;
end;
А во всех ли языках есть String[25]? Или что-нибудь другое выдумывать??? Как Вы считаете?
Defunct (2005-09-13 01:17:00) [11]Цукор 5 (13.09.05 01:11) [28]
вот и гут ;>
ps: я не настаиваю именно на таком решении, возможно есть решение и лучше. Тем не менее очень рад, что вы поняли о чем речь ;>
Цукор 5 (2005-09-13 01:11:00) [12]2 Defunct
Спасибо. Буду знать.Теперь вроде понятно.
Defunct (2005-09-13 01:07:00) [13]Цукор 5 (13.09.05 01:01) [25]
> Хм... а откуда взялось implementation в DLL?
Что значит откуда?
Кто мешает в теле DLL подключить модуль?
library MyLibrary;
uses MyUnit;
exports
OpenDevice,
ReadDevice,
CloseDevice,
GetItem,
Count;
begin
end.
> так я считаю,что это глобальная переменная.
неправильно считаете.
unit MyUnit;
interface
procedure OpenDevice;
procedure ReadDevice;
procedure CloseDevice;
function Count:integer;
function GetItem(idx:integer):TMyType;
implementation
var
DataToExport : Array of TMyType;
...
end.
DataToExport - не более чем локальная переменная модуля MyUnit.
Германн (2005-09-13 01:06:00) [14]2 Цукор 5
А что ты так сфокусировался на "глобальности" переменных в DLL?
Цукор 5 (2005-09-13 01:01:00) [15]2 Defunct © (13.09.05 00:52) [23]
Хм... а откуда взялось implementation в DLL?
var
DataToExport : Array of SomeType;
> этот массив локален для модуля в котором он описан
Как по мне...так я считаю,что это глобальная переменная.Хорошо,а что ж тогда глобальная переменная???
Цукор 5 (2005-09-13 00:57:00) [16]2 Defunct © (13.09.05 00:49) [22]
Вероятно я не понял Вас,а Вы меня. С телом DLL я как-нибудь сам разберусь. Мне непонятно следующее.
Итак :
>ReadDevice(..); // считает весь блок данных с устройства в массив
> GetItem // передаст некую часть массива в хост-приложение
Две ф-ции.Одна создает массив,вторая выберает и передает. Где и как это все хранить? Вот я о чем.
Defunct (2005-09-13 00:52:00) [17]> Но я никак не могу понять,как это реализовать без глобальной переменной в DLL.
Очень просто, например так:
implementation
var
DataToExport : Array of SomeType; <--- этот массив локален для модуля в котором он описан.
Defunct (2005-09-13 00:49:00) [18]> Цукор 5
экспортируем сл. функции:
OpenDevice;
ReadDevice;
CloseDevice;
и также для работы с массивом (буфером внутри dll)
GetItem;
SetItem;
Count;
далее используем их так
OpenDevice(..);
ReadDevice(..);
for i:=0 to Count-1 do
begin
zzz := GetItem;
end;
CloseDevice(..);
OpenDevice/ReadDevice/CloseDevice не обязательно экспортировать, их можно просто вызвать внутри функции Count.
Цукор 5 (2005-09-13 00:43:00) [19]2 Defunct © (12.09.05 03:04) [13]
Хотя стоп...
>Например, при вызове GetCount пусть DLL и прочитает из устройства все значения себе в массив.
Этот вариант мне приемлим.Но я никак не могу понять,как это реализовать без глобальной переменной в DLL. Ведь одна ф-ция должна создать "массив",а вторая выбирать из него данные.
Defunct (2005-09-13 00:41:00) [20]> Цукор 5 (13.09.05 00:37) [19]
Интересно, в каком месте?