Как сделать подобную структуру в C ++ для этого в Delphi - PullRequest
0 голосов
/ 13 января 2020

Моя программа получает сообщения WM_COPYDATA, содержащие указатель на структуру, которая выглядит в Delphi следующим образом:

type
  arr_geo_t = array[0..5000] of packed record
    nr : string[15];
    x,y,h : double;
    k : string[10];
  end;
  parr_geo_t = ^arr_geo_t;

Вопрос в том, как создать аналог в C ++?

Когда я определяю что-то вроде этого:

typedef struct
{
    char nr[5000][15];
    double x[5000];
    double y[5000];
    double h[5000];
    char k[5000][10];
} arr_geo_t, *parr_geo_t;

и пытаюсь получить данные, я ничего не получаю.

Ответы [ 2 ]

4 голосов
/ 13 января 2020

В коде Delphi arr_geo_t - это массив записей анонимного типа, а не запись массивов, как вы объявили в своем коде C ++. Правильный перевод C ++ объявлений Delphi будет выглядеть примерно так:

#include <pshpack1.h> // #pragma pack(push, 1), etc
typedef struct
{
    char nr[16];
    double x,y,h;
    char k[11];
} arr_geo_t[5001];
#include <poppack.h> // #pragma pack(pop), etc

typedef arr_geo_t *parr_geo_t;

Обратите внимание, что диапазоны массивов Delphi являются включающими, поэтому 0..5000 обозначает 5001 элемент, проиндексированный от индекса 0 до индекса 5000, включительно.

Также обратите внимание, что в массивах char[] есть еще 1 char, которые вы не учитываете. Это связано с тем, что в Delphi string[N] представляет собой ShortString , строковый тип фиксированной длины на основе AnsiChar, где N является максимальным числом AnsiChar s разрешено и имеет префикс 1 AnsiChar, указывающий, сколько фактических AnsiChar s в строке. Длина строки равна индексу 0, а символьные данные начинаются с индекса 1.

Если вы переводите код Delphi специально в C ++ Builder, вы можете использовать SmallString* Шаблон 1026 * вместо char[] массивов:

#include <System.hpp>

#include <pshpack1.h> // #pragma pack(push, 1), etc
typedef struct
{
    System::SmallString<15> nr;
    double x,y,h;
    System::SmallString<10> k;
} arr_geo_t[5001];
#include <poppack.h> // #pragma pack(pop), etc

typedef arr_geo_t *parr_geo_t;

Если вы переводите в C ++ 11 или более позднюю версию, вы можете очистить typedef s с помощью операторов using вместо:

#include <array>
//#include <System.hpp>

#include <pshpack1.h> // #pragma pack(push, 1), etc
struct arr_geo_data_t
{
    std::array<char, 16> nr; // or: System::SmallString<15> nr;
    double x,y,h;
    std::array<char, 11> k; // or: System::SmallString<10> k;
};
#include <poppack.h> // #pragma pack(pop), etc

using arr_geo_t = std::array<arr_geo_data_t, 5001>;
using parr_geo_t = arr_geo_t*;
0 голосов
/ 13 января 2020

Здесь есть проблема заказа. У вас есть массив структуры, а не количество массивов элементов данных.

Я думаю, что вы можете обнаружить, что следующее является более близким, но я сожалею delphi внутренние типы больше не важны мне!

struct arr_geo_t 
{
  struct record 
  {
    char nr[15];
    double x,y,h;
    char k[10];
  } array[5001];

};

Обратите внимание, что я не знаю, насколько хорошо работает упакованная запись в delphi. c / c ++ гарантирует, что двойники будут выровнены по 8-байтовым границам, эффективно увеличивая, например, nr до 16 символов. Вся структура также будет выровнена по 8-байтовым границам, поэтому эффективный размер k также будет равен 16. На некоторых компьютерах и при некоторых настройках компилятора двойные значения просто не могут быть доступны по невыровненным адресам.

При условии, что строки delphi основаны на символах, а не на Unicode.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...