我的程序通过包含指向结构的指针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;
并尝试检索数据,我一无所获。
在 Delphi 代码中,arr_geo_t
是匿名类型的记录数组,而不是您在C++代码中声明的数组记录。 德尔菲宣言的正确C++翻译看起来更像这样:
#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
表示从索引 0 到索引 5000(包括索引 5000(的 5001 个元素。
另请注意,char[]
数组中还有 1 个您未考虑的char
。 这是因为在 Delphi 中,string[N]
是 ShortString,这是一种基于AnsiChar
的固定长度字符串类型,其中N
是允许的最大AnsiChar
秒数,并以 1AnsiChar
为前缀,指定字符串中有多少个实际AnsiChar
。 字符串长度从索引 0 处开始,字符数据从索引 1 开始。
如果要将 Delphi 代码专门转换为 C++Builder,则可以使用SmallString
模板而不是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 或更高版本,则可以通过using
语句清理typedef
:
#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*;
这里有一个排序问题。您有一个结构数组,而不是多个数据成员数组。
我想您可能会发现以下内容更接近匹配,但很抱歉德尔福内部类型对我来说不再重要!
struct arr_geo_t
{
struct record
{
char nr[15];
double x,y,h;
char k[10];
} array[5001];
};
另请注意,我不知道打包记录在德尔福的效果如何。 C/C++ 将确保双精度在 8 字节边界上对齐,例如,有效地将 NR 扩展到 16 个字符。整个结构也将对齐到 8 字节边界,因此 k 的有效大小也将为 16。在某些计算机上,并且使用某些编译器设置,根本无法从未对齐的地址访问双精度。
这是假设 delphi 字符串是基于字符而不是基于 unicode 的。