Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Подскажите как реализовать такую структуру данных, в DLL 
:(
    Опции темы
Гость_Игорь
Дата 15.7.2005, 13:02 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Здравствуйте.

Подскажите пжл как реализовать такое:

Я хочу в DLL зашить некую информацию например о ее функции (плагине).
Написал такое:

Код

  PPluginInfo = ^TPluginInfo;
  TPluginInfo = record

    Name : ShortString;
    Version : ShortString;
    Description : ShortString;
    Vendor : ShortString;
    ArgumentCount : integer;

    ArgumentCount : integer[s];    
    Argument : TArgumentInfo;
  end;


Но...
Затык номер 1 - проблема со стрингами.
Вроде все компилится и работает,но в тескстовых полях - каша.
Я читал что нельзя использовать Делфовские строки в ДЛЛ -
а использовать PChar, но тогда вместо текстовых полей будут
указатели PChar, а мне надо чтоб структура была нерперывной -
т.е. в памяти строки располагались одна за другой, а не их указатели

Затык номер 2 -
неодинаковое количество Argument : TArgumentInfo в структурах.
т.е. в одном плагине их 2, в другом 3...
Компилятор требует точного указания количеста (я его понимаю).

Как в терминах Делфи можно указать, что например после поля ArgumentCount
размещается несколько TArgumentInfo ??
Динамические массивы исключаются - т.к. я уже упоминал
мне необходимо чтобы поля располагались один за другим
а не их указатели.

Кто решал подобные задачи.
Натолкните на идею
заранее спасибо.



  Вверх
Girder
Дата 15.7.2005, 13:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй 2
***


Профиль
Группа: Участник Клуба
Сообщений: 1993
Регистрация: 12.5.2004

Репутация: 31
Всего: 155



1. Передавай указатель на буфер где храняться все структуры
2. Передавай полную длину структур в буфере(в байтах)
3. Используй: packed record

4. При получении указателя на структуры... обрабатывай их например так:
Код

var
 vvv: TPluginInfo; 
 Buf: PPluginInfo;
 X:integer;
//...
begin
//...
while X>0 do
 begin
  vvv:=PPluginInfo(Buf)^;
  //обработка vvv
  Buf:=Pointer(DWord(Buf)+SizeOf(TPluginInfo));
  x:=x-SizeOf(TPluginInfo);
 end;
//...


Это сообщение отредактировал(а) Girder - 15.7.2005, 13:48


--------------------
Как слышим, так и пишим.
Истина где-то там...
PM   Вверх
Гость_Игорь
Дата 15.7.2005, 17:28 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Не работает, поскольку строки в памяти лежат ХЗ как
(под строками я подразумеваю последовательность символов-байтов
а не Делфовский string)

т.е. если объявить
A : array [0..3] of char = 'yes'#0;
B : array [0..2] of char = 'no'#0;

то это НЕ значит что в памяти будет лежать 'y','e','s',0,'n','o',0

такая же ситуация и с
PChar и с String и с...
кароче я все перепробовал

Т.е. задача сводится к тому как правильно объявить строки
чтоб они лежали правильно-друг за другом как указано выше

  Вверх
Girder
Дата 15.7.2005, 21:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй 2
***


Профиль
Группа: Участник Клуба
Сообщений: 1993
Регистрация: 12.5.2004

Репутация: 31
Всего: 155



Вот пример smile

DLL:
Код
library DLLX;

uses
 Windows,SysUtils;

{$R *.res}

var cInt:integer=0;
    r:DWord=0;

type
  PPluginInfoA = ^TPluginInfoA;
  TPluginInfoA = packed record
    Str1:array [1..20] of char;
    Str2:array [1..20] of char;
    Str3:array [1..200] of char;
    Int1:integer;
    Int2:DWord;
  end;
  PPluginInfoW = ^TPluginInfoW;
  TPluginInfoW = packed record
    Str1:array [1..20] of WideChar;
    Str2:array [1..20] of WideChar;
    Str3:array [1..200] of WideChar;
    Int1:integer;
    Int2:DWord;
  end;

function Ay_A(XXX:PPluginInfoA; SizeXXX:DWord):DWord; stdcall;
var s:string;
begin
 if r=0 then
  begin
   Randomize;
   r:=Random(10)+1;
  end;
 Result:=r*SizeOf(TPluginInfoA);
 if XXX=nil then exit;
 if SizeXXX<r*SizeOf(TPluginInfoA) then
  begin
   Result:=0;
   exit;
  end;
 repeat
  dec(r);
  s:=TimeToStr(Now);
  CopyMemory(PChar(@XXX^.Str1),PChar(s),Length(s)+1);
  s:=DateToStr(Now);
  CopyMemory(PChar(@XXX^.Str2),PChar(s),Length(s)+1);
  s:=IntToStr(cInt);
  CopyMemory(PChar(@XXX^.Str3),PChar(s),Length(s)+1);
  XXX^.Int1:=cInt;
  XXX^.Int2:=r;
  XXX:=PPluginInfoA(DWord(XXX)+SizeOf(TPluginInfoA));
  inc(cInt);
 until (r=0);
end;

function Ay_W(XXX:PPluginInfoW; SizeXXX:DWord):DWord; stdcall;
var s:WideString;
begin
 if r=0 then
  begin
   Randomize;
   r:=Random(10)+1;
  end;
 Result:=r*SizeOf(TPluginInfoW);
 if XXX=nil then exit;
 if SizeXXX<r*SizeOf(TPluginInfoW) then
  begin
   Result:=0;
   exit;
  end;
 repeat
  dec(r);
  s:=TimeToStr(Now);
  CopyMemory(@XXX^.Str1,PWideChar(s),(Length(s)+1)*SizeOf(WideChar));
  s:=DateToStr(Now);
  CopyMemory(@XXX^.Str2,PWideChar(s),(Length(s)+1)*SizeOf(WideChar));
  s:=IntToStr(cInt);
  CopyMemory(@XXX^.Str3,PWideChar(s),(Length(s)+1)*SizeOf(WideChar));
  XXX^.Int1:=cInt;
  XXX^.Int2:=r;
  XXX:=PPluginInfoW(DWord(XXX)+SizeOf(TPluginInfoW));
  inc(cInt);
 until (r=0);
end;

exports Ay_A;
exports Ay_W;

begin
end.


Использование dll:
Код
type
  PPluginInfoA = ^TPluginInfoA;
  TPluginInfoA = packed record
    Str1:array [1..20] of char;
    Str2:array [1..20] of char;
    Str3:array [1..200] of char;
    Int1:integer;
    Int2:DWord;
  end;
  PPluginInfoW = ^TPluginInfoW;
  TPluginInfoW = packed record
    Str1:array [1..20] of WideChar;
    Str2:array [1..20] of WideChar;
    Str3:array [1..200] of WideChar;
    Int1:integer;
    Int2:DWord;
  end;

procedure TForm1.Button1Click(Sender: TObject);
type TAy_A=function (XXX:PPluginInfoA; SizeXXX:DWord):DWord; stdcall;
var DLL:DWord;
    Ay_A:TAy_A;
    Size:DWord;
    p,t:PPluginInfoA;
begin
 Memo1.Lines.Clear;
 DLL:=LoadLibrary('DLLX.dll');
 if DLL<>0 then
  begin
   Ay_A:=GetProcAddress(DLL,'Ay_A');
   if assigned(Ay_A) then
    begin
     Size:=Ay_A(nil,0);
     if Size>0 then
      begin
       GetMem(p,Size);
       t:=p;
       Size:=Ay_A(p,Size);
       if Size>0 then
        begin
         while integer(Size)>0 do
          begin
           Memo1.Lines.Add('___________________');
           Memo1.Lines.Add(t^.Str1);
           Memo1.Lines.Add(t^.Str2);
           Memo1.Lines.Add(t^.Str3);
           Memo1.Lines.Add(IntToStr(t^.Int1));
           Memo1.Lines.Add(IntToStr(t^.Int2));
           Memo1.Lines.Add('___________________');
           t:=PPluginInfoA(DWord(t)+SizeOf(TPluginInfoA));
           Size:=Size-SizeOf(TPluginInfoA);
          end;
        end else Caption:='Размер буфера мал!';
       FreeMem(p,Size*10);
      end else Caption:='Нет ни чего!';
    end;
   FreeLibrary(DLL);
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
type TAy_W=function (XXX:PPluginInfoW; SizeXXX:DWord):DWord; stdcall;
var DLL:DWord;
    Ay_W:TAy_W;
    Size:DWord;
    p,t:PPluginInfoW;
begin
 Memo1.Lines.Clear;
 DLL:=LoadLibrary('DLLX.dll');
 if DLL<>0 then
  begin
   Ay_W:=GetProcAddress(DLL,'Ay_W');
   if assigned(Ay_W) then
    begin
     Size:=Ay_W(nil,0);
     if Size>0 then
      begin
       GetMem(p,Size);
       t:=p;
       Size:=Ay_W(p,Size);
       if Size>0 then
        begin
         while integer(Size)>0 do
          begin
           Memo1.Lines.Add('___________________');
           Memo1.Lines.Add(t^.Str1);
           Memo1.Lines.Add(t^.Str2);
           Memo1.Lines.Add(t^.Str3);
           Memo1.Lines.Add(IntToStr(t^.Int1));
           Memo1.Lines.Add(IntToStr(t^.Int2));
           Memo1.Lines.Add('___________________');
           t:=PPluginInfoW(DWord(t)+SizeOf(TPluginInfoW));
           Size:=Size-SizeOf(TPluginInfoW);
          end;
        end else Caption:='Размер буфера мал!';
       FreeMem(p,Size);
      end else Caption:='Нет ни чего!';
    end;
   FreeLibrary(DLL);
  end;
end;



--------------------
Как слышим, так и пишим.
Истина где-то там...
PM   Вверх
vadims
Дата 15.7.2005, 21:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 305
Регистрация: 8.6.2005

Репутация: нет
Всего: 17



Гость_Игорь

Имхо

Никак - в твоем варианте - на мой взгляд зря ты ругаешь Дельфи
у него тоже ведь система есть
1 байт - длина строки
+ сама строка

Но мне кажется что у тебя проблемы то нет - просто ты не очень хорошо понимаешь объявление-результат




--------------------
Cpu not found ! Press any key for software emulation.
PM MAIL   Вверх
Гость_Игорь
Дата 15.7.2005, 22:56 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Girder
Спасибо за код. Буду разбираться.
Примерно такое же намаслал и я smile

Но у тебя другой подход. И, наверно, правильней чем у меня.


vadims
Согласен с тобой.
Как оказалось простые, на первый взгляд вещи, в Делфи
не так у ж просты.


А вообще, такую задачу надо делать на asm-e.
И размер ДЛЛ поменьше получается... smile

  Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

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

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0569 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.