Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Динамический массив и DLL


Автор: former 19.1.2007, 00:37
Появилась такая проблема. Не могу заполнить динамический массив в DLL, переданный из программы.

Текст приложения:
Код

unit uMainForm;

interface

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

type
  TMainForm = class(TForm)
     Button1:TButton;
     ML:TValueListEditor;
     procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

const PluginsM:array[1..2] of PAnsiChar = ('mmgll001.dll','mmgll002.dll');

var
  MainForm: TMMGMainForm;
  ParCount:integer;
  InitParam:array of real;

implementation

{$R *.dfm}


procedure TMainForm.Button1Click(Sender: TObject);
var LibHandle: THandle;
    fGiveParToVar: procedure (ParMass:array of real; MatL:TValueListEditor);  
begin
  SetLength(InitParam,0);
  for i:=1 to ParCount do SetLength(InitParam,Length(InitParam)+i);
  LibHandle := LoadLibrary(PluginsM[CurentConstr]);
  if LibHandle = 0 then
    raise Exception.Create('Невозможно загрузить библиотеку '+PluginsM[CurentConstr])
  else
  begin
    try @fGiveParToVar:= GetProcAddress(LibHandle, 'GiveParToVar');
      if @fGiveParToVar <> nil then fGiveParToVar(InitParam,MList);
    except
      on E: Exception do ShowMessage('Ошибка: ' + E.Message);
    end;
  end;
  FreeLibrary(LibHandle);
end;

end;


Текст DLL:
Код

library mmgll001;

uses
  ShareMem,
  SysUtils,
  Classes,
  ValEdit;

{$R *.res}

procedure GiveParToVar(ParMass:array of real; MatL:TValueListEditor);
begin

  ParMass[0]:=StrToFloat(MatL.Cells[1,1]);
end;

exports
  GiveParToVar;

begin
end.


Подскажите, в чём ошибка?

Автор: skyboy 19.1.2007, 02:00
Цитата(former @  18.1.2007,  23:37 Найти цитируемый пост)
Не могу заполнить динамический массив в DLL, переданный из программы.

почему? религия не позволяет? 
давай так: 
- если вываливается ошибка - ты о ней сообщаешь в первом, а не в пятом посте темы;
- если наблюдается логическая нестыковка ожидаемого и полученного - тщательно описываешь ожидаемое и приводишь пример полученного;
- если просто забыл запустить компилятор - помечаешь вопрос решенным;
договорились? 
пока догадываться не буду, толь замечу, что модуль sharemem должен быть подключен и в списке uses project.dpr

Добавлено @ 02:05 
Цитата(former @  18.1.2007,  23:37 Найти цитируемый пост)
@fGiveParToVar

насколько мне помнится, оператор взятия адреса необязателен. если вообще допустим.

Автор: Guedda 19.1.2007, 02:07
Интересно. А где в коде ты выделяешь под динамический массив память?
Код

SetLength() //рулит ;)

Автор: Snowy 19.1.2007, 02:38
Guedda, 
Цитата(former @  19.1.2007,  00:37 Найти цитируемый пост)
  SetLength(InitParam,0);  for i:=1 to ParCount do SetLength(InitParam,Length(InitParam)+i);
Правда более нелепого выделения я ещё не видел.
Зачем цикл??!!!

Автор: VICTAR 19.1.2007, 02:41
Я так подозреваю, что это должно выглядеть так:
Код

fGiveParToVar: procedure (var ParMass:array of real; MatL:TValueListEditor);  

иначе ИМХО просто нет смысла в этой процедуре.

И обязательно

Цитата(skyboy @  19.1.2007,  02:00 Найти цитируемый пост)
модуль sharemem должен быть подключен и в списке uses project.dpr


ЗЫ может здесь скрытый смысл, но
Код

for i:=1 to ParCount do SetLength(InitParam,Length(InitParam)+i);

легче сделать 
Код

SetLength(InitParam, ParCount);


Автор: former 19.1.2007, 08:45
Приношу извинения за не полностью отражённую проблему и некоторые ошибки в приведённом коде. Просто, вытаскивал этот кусок кода из основной программы и не всё правильно скопировал. 

Главная проблема состоит в том, что массив после возврата из  DLL остаётся пустым.

Цитата(skyboy @  19.1.2007,  02:00 Найти цитируемый пост)
пока догадываться не буду, толь замечу, что модуль sharemem должен быть подключен и в списке uses project.dpr


skyboy, модуль ShareMem к проекту у меня подключен.


Цитата(Guedda @  19.1.2007,  02:07 Найти цитируемый пост)
Интересно. А где в коде ты выделяешь под динамический массив память?

код Pascal/Delphi
1: SetLength() //рулит ;)


Цитата(Snowy @  19.1.2007,  02:38 Найти цитируемый пост)
Правда более нелепого выделения я ещё не видел.
Зачем цикл??!!! 


Guedda, Snowy и VICTAR абсолютно с вами согласен. Ерунду написал.


Цитата(VICTAR @  19.1.2007,  02:41 Найти цитируемый пост)
Я так подозреваю, что это должно выглядеть так:
код Pascal/Delphi
1: fGiveParToVar: procedure (var ParMass:array of real; MatL:TValueListEditor);


VICTAR, ты абсолютно прав. Всё заработало.

Надо выспаться и быть по внимательнее, а то начинаю в трёх соснах блуждать.

Всем большое спасибо за помощь.

Добавлено @ 08:46 
Всем ставлю по плюсу.  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)