Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.67/9: Рейтинг темы: голосов - 9, средняя оценка - 4.67
0 / 0 / 0
Регистрация: 08.01.2023
Сообщений: 36

Ошибки при передаче в dll массива и его возвращение

10.04.2023, 20:45. Показов 3592. Ответов 49

Студворк — интернет-сервис помощи студентам
Приветствую форумчан. Возник вопрос: как передать массив из действительных чисел в dll, а потом вернуть полученный результат - такой же массив. Попытался найти что-нибудь в интернете по этому поводу, но ничего полезного для себя найти не смог. Мое задание: есть последовательность, ее значения необходимо "сгладить", но мне либо просто не скомпилировать какой-либо из файлов, либо вылезает ошибка при работе кода, что " '' is not a valid floating point value. ".
Кто-нибудь может дать совет моим начинаниям?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
10.04.2023, 20:45
Ответы с готовыми решениями:

Одинаково ли быстродействие: 1. при передаче параметров в функцию или 2. создание кортежа и передаче его в функцию?
Одинаково ли быстродействие: 1. при передаче параметров в функцию или 2. создание кортежа и передаче его в функцию? Зависит ли это от...

Возвращение массива строк из dll
Здравствуйте! Помогите, пожалуйста, со следующей проблемой. Имеется проект на C# и dll на С++. Я пытаюсь вернуть из функции,...

Ошибка при отладке ActiveX.DLL при передаче объекта форма
в вызывающем модуле Функция(Me) в ActiveX Sub Функция(frm as Object) typeof frm is form - выдает False в режиме отладки ActiveX...

49
Модератор
4153 / 2362 / 814
Регистрация: 15.11.2015
Сообщений: 9,496
12.04.2023, 10:01
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Couguar Посмотреть сообщение
Я думал, что он по такому же принципу работает, как и статический массив.
У статического нумерация как укажешь. Можно и от -5 до 5, например. А у динамических только с 0.

Добавлено через 3 часа 34 минуты
Цитата Сообщение от Couguar Посмотреть сообщение
Проблема решена. Сделал все через функцию, а не процедуру.
Проблема явно не в этом. А библиотеку после изменений точно перекомпилировал?

Вот так и передаёт и возвращает нормально. Код основной программы:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Grids, StdCtrls;
 
type
    Tpar = array of double;
    PTpar = ^Tpar;
 
type
  TForm1 = class(TForm)
    Button1: TButton;
    StringGrid1: TStringGrid;
    StringGrid2: TStringGrid;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
procedure arr(const a: Tpar; var b: Tpar); stdcall; external 'Project2.dll';
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  with StringGrid1 do begin
    FixedCols := 0;
    Options := Options + [goEditing];
    ColCount := 10;
    RowCount := 2;
  end;
  with StringGrid2 do begin
    FixedCols := 0;
    ColCount := 10;
    RowCount := 2;
  end;
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var
  a, b: Tpar;
  i, n: integer;
begin
  n := StringGrid1.ColCount;
  SetLength(a, n);
  SetLength(b, n);
  for i := 0 to High(a) do
    a[i] := StrToFloatDef(StringGrid1.Cells[i, 1], 0);
 
  arr(a, b);
 
  StringGrid2.ColCount := Length(b);
  for i := 0 to High(b) do
    StringGrid2.Cells[i, 1] := FloatToStr(b[i]);
end;
 
end.
Код библиотеки:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
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
  ShareMem,
  SysUtils,
  Classes;
 
{$R *.res}
 
type
    Tpar = array of double;
    PTpar = ^Tpar;
 
procedure arr(const a: Tpar; var b: Tpar); stdcall;
var
  i: integer;
begin
  SetLength(b, length(a));
  b[Low(b)] := a[Low(a)];
  b[High(b)] := a[High(b)];
  for i := Low(b) + 1 to High(b) - 1 do
      b[i] := (a[i - 1] + a[i] + a[i + 1] / 3);
end;
 
exports
    arr;
 
begin
end.
Сейчас ещё переделаю для передачи по ссылке, будет без использования ShareMem.

Добавлено через 10 минут
Через указатели так получилось:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Grids, StdCtrls;
 
type
  TForm1 = class(TForm)
    Button1: TButton;
    StringGrid1: TStringGrid;
    StringGrid2: TStringGrid;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
type
  PDoubleArray = ^TDoubleArray;
  TDoubleArray = array[0..32767] of double;
 
procedure arr(a, b: PDoubleArray; Count: integer); stdcall; external 'Project2.dll';
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  with StringGrid1 do begin
    FixedCols := 0;
    Options := Options + [goEditing];
    ColCount := 10;
    RowCount := 2;
  end;
  with StringGrid2 do begin
    FixedCols := 0;
    ColCount := 10;
    RowCount := 2;
  end;
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var
  a, b: array of double;
  i, n: integer;
begin
  n := StringGrid1.ColCount;
  SetLength(a, n);
  SetLength(b, n); // Оба массива готовятся заранее
  for i := 0 to High(a) do
    a[i] := StrToFloatDef(StringGrid1.Cells[i, 1], 0);
 
  arr(@a[0], @b[0], Length(a));
 
  StringGrid2.ColCount := Length(b);
  for i := 0 to High(b) do
    StringGrid2.Cells[i, 1] := FloatToStr(b[i]);
end;
 
end.
Библиотека:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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}
 
type
  PDoubleArray = ^TDoubleArray;
  TDoubleArray = array[0..32767] of double;
 
procedure arr(a, b: PDoubleArray; Count: integer); stdcall;
var
  i: integer;
begin
  b[0] := a[0];
  b[Count-1] := a[Count-1];
  for i := 1 to Count-2 do
    b[i] := (a[i - 1] + a[i] + a[i + 1] / 3);
end;
 
exports
    arr;
 
begin
end.
0
631 / 526 / 104
Регистрация: 05.08.2022
Сообщений: 2,810
12.04.2023, 10:10
Цитата Сообщение от AzAtom Посмотреть сообщение
Сейчас ещё переделаю для передачи по ссылке, будет без использования ShareMem.
Покажите потом код и напишите какой результат
Что-то мне это подозрительно.
0
Модератор
4153 / 2362 / 814
Регистрация: 15.11.2015
Сообщений: 9,496
13.04.2023, 09:14
Цитата Сообщение от KSergey9 Посмотреть сообщение
Покажите потом код и напишите какой результат
В предыдущем сообщении показано и написано.
0
631 / 526 / 104
Регистрация: 05.08.2022
Сообщений: 2,810
13.04.2023, 09:27
Цитата Сообщение от AzAtom Посмотреть сообщение
В предыдущем сообщении показано и написано.
Так было обещано
Цитата Сообщение от AzAtom Посмотреть сообщение
переделаю для передачи по ссылке, будет без использования ShareMem.
а показано
Цитата Сообщение от AzAtom Посмотреть сообщение
Через указатели
Хотелось увидеть именно "по ссылке без ShareMem".

Впрочем, суть-то не в указателях у вас.
Суть в том основная переделки, что вы массив b изначально в основной программе выделяете, а не внутри функции dll.
Если бы вы так изначально сделали даже на обычных array of дельфовых - у вас и так бы всё заработало, причем даже без ShareMem.
Основная же и была у вас заморочка в том, что вы внутри функции arr() массив выделяли. И я думал, что это принципиальное требование.
0
Модератор
4153 / 2362 / 814
Регистрация: 15.11.2015
Сообщений: 9,496
13.04.2023, 09:58
KSergey9, что-то я не пойму, чем у вас ссылки отличаются от указателей в данном случае?

Добавлено через 4 минуты
Цитата Сообщение от KSergey9 Посмотреть сообщение
Основная же и была у вас заморочка в том, что вы внутри функции arr() массив выделяли.
Это ТС привёл код, где память для выходного массива выделялась в библиотеке. Отсюда и вышло требование использования ShareMem. А я предложил подготовить память заранее, чтобы библиотека ничего не выделяла, а просто заполняла готовый буфер.
0
631 / 526 / 104
Регистрация: 05.08.2022
Сообщений: 2,810
13.04.2023, 10:05
Цитата Сообщение от AzAtom Посмотреть сообщение
Это ТС привёл код, где память для выходного массива выделялась в библиотеке. Отсюда и вышло требование использования ShareMem. А я предложил
Айм сорри, перепутал я кто ТС, а кто отвечает
Впрочем, как я и писал выше, суть именно вот в этом вашей переделки "под указатели"
Цитата Сообщение от AzAtom Посмотреть сообщение
А я предложил подготовить память заранее
а не в указателях как таковых. Что не было указано вами изначально.

Добавлено через 2 минуты
Цитата Сообщение от AzAtom Посмотреть сообщение
что-то я не пойму, чем у вас ссылки отличаются от указателей в данном случае?
Ссылка от указателя отличается абсолютно всем.
А в приведённом вами коде полностью отличается тем, что ссылка на динамический массив и указатель на первый элемент массива (ну ок, на начало элементов массива) - абсолютно разные штуки. Хотя бы тем, что в массиве динамическом вы и так знаете его размер, а по указателю о размере ничего сказать нельзя, только отдельным параметром передавать. Я не про удобство там или еще что, я про то, что это абсолютно разные штуки в языке, не смотря даже на то, что реализуются одинаковыми штуками внутри. Но то, что с точки зрения языка это разное - даёт разные им свойства что ли. На уровне языка Delphi.
0
Модератор
 Аватар для D1973
9954 / 6490 / 2461
Регистрация: 21.01.2014
Сообщений: 27,495
Записей в блоге: 3
13.04.2023, 10:06
Цитата Сообщение от AzAtom Посмотреть сообщение
чтобы библиотека ничего не выделяла, а просто заполняла готовый буфер
Как по мне, использование DLL в случаях, подобных этому - чушь несусветная, а уж если еще и вот так с массивом поступить, то, согласитесь, вообще весь смысл использования DLL теряется...
0
Модератор
4153 / 2362 / 814
Регистрация: 15.11.2015
Сообщений: 9,496
13.04.2023, 10:12
KSergey9, понял, как вы воспринимаете ссылку. В общем, я имел в виду именно указатель на начало буфера с данными.

Добавлено через 1 минуту
Цитата Сообщение от D1973 Посмотреть сообщение
вообще весь смысл использования DLL теряется...
Не всегда. В том же WinAPI такое используется сплошь и рядом. Основа, так сказать.

Добавлено через 1 минуту
Цитата Сообщение от KSergey9 Посмотреть сообщение
суть именно вот в этом вашей переделки "под указатели"
Суть была избавиться от ShareMem.
0
631 / 526 / 104
Регистрация: 05.08.2022
Сообщений: 2,810
13.04.2023, 10:19
Цитата Сообщение от D1973 Посмотреть сообщение
Как по мне, использование DLL в случаях, подобных этому - чушь несусветная,
Это скорее всего просто учебная задача, понять/пощупать как оно вообще с DLL работать.
Вполне нормальная задача.

Добавлено через 3 минуты
Цитата Сообщение от AzAtom Посмотреть сообщение
Суть была избавиться от ShareMem.
Для этого не надо было уходить в указатели. Да и статический массив не обязателен был.
Достаточно было выделять массив заранее, а не внутри arr()

Впрочем, "бояться" ShareMem не вижу никакого смысла. Это сделанное для вас готовое волшебство. При условии, конечно, что вы остаётесь в рамках только Delphi для основной программы и dll.
0
Модератор
4153 / 2362 / 814
Регистрация: 15.11.2015
Сообщений: 9,496
13.04.2023, 10:32
Цитата Сообщение от KSergey9 Посмотреть сообщение
в массиве динамическом вы и так знаете его размер, а по указателю о размере ничего сказать нельзя, только отдельным параметром передавать.
Теоретически, можно такое и с указателем провернуть. Мы же знаем, как организован динамический массив и откуда взять его размер? И если передаём указатель на 0 элемент дин. массива, то всё уже сделано за нас. Нам остаётся только прочитать размер массива. То же самое можно сделать и через указатель на просто кусок памяти, только вручную, и буфер нужно подготавливать соответственным образом.
Но ТСу подобное вряд ли нужно, так что, забудем про это.

Добавлено через 41 секунду
Цитата Сообщение от KSergey9 Посмотреть сообщение
При условии, конечно, что вы остаётесь в рамках только Delphi для основной программы и dll.
Вот именно по этому, а не по причине боязни.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
13.04.2023, 10:32

Ошибка при передаче текста из ComboBox в DLL
Подскажите где я ошибся, при передачи текста из CombaBox в dll. текст длл extern "C" char* __declspec(dllexport)...

Ошибки при передаче DataTable
Есть сервис и клиент все работает нормально на простых данных, например строках, но мне нужно передать datatable, при попытке это сделать...

Возвращение к условию при возникновении ошибки
Добрый день! Есть вот такой код: On Error GoTo er: G = MsgBox("Óäàëèòü çàïèñü?", vbQuestion + vbYesNo,...

Проблема при передаче параметров функции из потока в dll
Здравствуйте, пишу программу, создающую com-объект из dll. При успешном создании получаю указатель на интерфейс и через него реализую метод...

STM32F105 CAN копятся ошибки при передаче
Здравствуйте. Все экспериментирую с канами и вылезла такая проблемка. На шине три устройства: 1. STM32F105 2. Софт Кан хакер и...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
50
Ответ Создать тему
Новые блоги и статьи
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru