Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Передача двумерных массивов по ссылке между Delphi и C++: обход препятствий и примеры кода

Delphi , Синтаксис , Массивы

Передача двумерных массивов по ссылке между Delphi и C++

При разработке API для приложения на Delphi (XE5), возникает необходимость передачи данных между функциями DLL и основной программой, написанной на C или C++. Одним из таких случаев является передача двумерных массивов, выделенных в памяти вызовом, для заполнения их значениями из DLL.

Проблема

Использование открытых массивов (open array) в Delphi не является удобным решением для передачи двумерных массивов, так как они содержат дополнительные данные, требующие имитации в C. В связи с этим, разработчики могут рассмотреть возможность использования арифметики указателей для прямой передачи адреса массива из C в DLL.

Пример кода

Пример кода, предоставленный в вопросе, демонстрирует функцию ShowArrayContents, которая принимает указатель на массив double и размер массива, и затем перебирает его, выводит значения и перемещается к следующему элементу с помощью инкрементации указателя.

library PDA;
uses
  System.StrUtils,
  System.SysUtils,
  Vcl.Dialogs;
{$R *.res}
function ShowArrayContents(APDouble: PDouble; size: Integer): integer; cdecl; export;
var
  i: Integer;
begin
  Result := 0;
  for i := 0 to size-1 do
  begin
    // Вывод значения
    MessageDlg(Format('%p -> %p -> %f', [@APDouble, APDouble, APDouble^]), mtWarning, [mbOK], 0);
    Inc(APDouble);
  end;
end;
exports
  ShowArrayContents;
begin
end.

C-код вызывает эту функцию, передавая указатель на первый элемент двумерного массива и его размер.

#include <stdio.h>
#include <tchar.h>
#include <stdlib.h>
#include <windows.h>

typedef int (*_ShowArrayContents)(double *, int);

char *dllname = "PDA.dll";
static HINSTANCE hInstanceControl;

_ShowArrayContents ShowArrayContents = NULL;

int _tmain(int argc, _TCHAR* argv[])
{
    double DVals[3][3] = { {1.23, 2.34, 3.45}, {4.56, 5.67, 6.78}, {7.89, 8.90, 9.01} };
    int i;

    hInstanceControl = LoadLibrary(dllname);

    if( hInstanceControl != NULL){
        ShowArrayContents =(_ShowArrayContents)GetProcAddress(hInstanceControl, "ShowArrayContents");
    } else {
        return 0;
    }

    // Тестовая программа:
    (*ShowArrayContents)(&DVals[0][0], 3 * 3);

    FreeLibrary(hInstanceControl);

    system("pause");
    return 0;
}

Решение

В ответе было подтверждено, что предложенный код работает, но его использование неудобно. Для таких задач можно использовать директиву $POINTERMATH, которая позволяет обращаться с указателями так, как это делается в C или C++. Например:

{$POINTERMATH ON}
function GetSum(arr: PDouble; len: Integer): Double; cdecl;
var
  i: Integer;
begin
  Result := 0.0;
  for i := 0 to len-1 do
    Result := Result + arr[i];
end;

Другой подход — копирование в массив типа TArray и дальнейшая обработка:

var
  x: TArray<Double>;
...
SetLength(x, len);
Move(arr^, Pointer(x)^, len*SizeOf(arr^));

Или использование цикла для копирования:

{$POINTERMATH ON}
var
  i: Integer;
  x: TArray<Double>;
...
SetLength(x, len);
for i := 0 to len-1 do
  x[i] := arr[i];

Выводы

Передача двумерных массивов по ссылке между Delphi и C++ может быть выполнена с использованием арифметики указателей, но для более удобной и надежной работы рекомендуется использовать директиву $POINTERMATH или копирование массива в тип TArray. Выбор метода зависит от конкретных задач и предпочтений разработчика.

Создано по материалам из источника по ссылке.

Передача двумерных массивов по ссылке между функциями DLL, написанными на Delphi, и основной программой на C++ для заполнения их значениями из DLL.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Массивы ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-03-14 10:29:33/0.003497838973999/0