|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
|||
|
|||
Передача массива из DLL в основную программу
В DLL у меня происходят вычисления и в основную программу передается массив записей.
Но, почему то после успешной отработки DLL я не могу работать с возвращенными данными Собственно код... Код:
Общий класс основной программы и DLL ... type TKoef = Record name: PChar; abbr: PChar; val_bgn: real; val_end: real; delta: real; criterion: boolean; cr_min: real; cr_max: real; dev_bgn: boolean; dev_end: boolean; dev_bgn_val: real; dev_end_val: real; info: PChar; valid: boolean; end; Основная программа ... type TArr = array of TKoef; TPArr = ^TArr; ... procedure TfMain.mModuleCalcClick(Sender: TObject); var Arr: TArr; PArr: TPArr; begin try try hDLL := LoadLibrary(PAnsiChar(FN)); @GetModuleData := nil; if hDLL >= 32 then begin @GetModuleData := GetProcAddress(hDLL,'GetModuleData'); if (@GetModuleData<>nil) then begin SetLength(Arr,5); PArr := Addr(Arr); if GetModuleData(ORG, PArr) then begin ---> вот здесь я пытаюсь работать с Arr, но вылетают ошибки end; end; end; finally @GetModuleData := nil; FreeLibrary(hDLL); end; except end; end; ... DLL ... const KOEF_CLOUNT = 5; type TArr = array[1..KOEF_CLOUNT] of TKoef; TPArr = ^TArr; ... function GetModuleData(dllORG: TOrganization; aPArr:TPArr): Boolean; stdcall; begin with aPArr^[1] do begin ... end; ... with aPArr^[5] do begin ... end; end; ... |
#2
|
|||
|
|||
Ну так в основной программе
Код:
array of TKoeff Код:
array [1..of KOEF_CLOUNT] TKoeff В основной программе надо Код:
type TArr = array of TKoef; TPArr = ^TKoef; // <<==-- Вот TGetModuleData = function (dllORG: TOrganization; aPArr:TPArr): Boolean; stdcall; ... PArr := @(Arr[0]); //<<==-- Вот if GetModuleData(ORG, PArr) ... |
#3
|
||||
|
||||
И еще в процедурах, которые возвращают данные в параметрах, обьявляй эти параметры после var.
Код:
function GetModuleData(dllORG: TOrganization;var aPArr:TPArr): Boolean; stdcall; |
#4
|
|||
|
|||
Всем спасибо.
Сделал так: передача массива не через указатель на массив, а собственно передача динамического массива. И в программе и в ДЛЛ стал использовать единый тип (динамический массив). Все работает. |
#5
|
|||
|
|||
Цитата:
А для такого способа не забывать внимательно читать комментарий, который Delphi пишет в заготовке проекта DLL. |
#6
|
|||
|
|||
Не совсем понял о чем речь...
|
#7
|
|||
|
|||
Цитата:
А вот это вредный совет. |
#8
|
||||
|
||||
Цитата:
Насчет поста о комментарии в DLL - я тоже ничего не понял. Там, кажись, написано о строках, а не динамических массивах. ИМХО все из-за совместимости dll для разных языков программирования. И ТС использует PChar, String нигде нет. |
#9
|
|||
|
|||
В алгоритме, который привёл автор топика, в DLL передаётся указатель на уже выделенную память, в DLL она только заполняется. Поэтому лишний var тут не нужен. Var может понадобится в случае, когда передаётся структура и в DLL она будет изменена. Посмотрите модуль windows.pas. Во многих случаях, когда в API функции требуется указатель на переменную или структуру, в паскале используется синтаксис в var. А когда нужен массив - используются указатели.
По поводу комментария - механизм работы со строками и динамическими массивами один и тот же. |