Как преобразовать объединение C ++ в Delphi

Я знаю, что об этом уже спрашивали, но я безуспешно пытаюсь преобразовать некоторые структуры / объединения C ++ в Delphi для использования Hikvision SDK.

Структуры / объединения C ++, которые я пытаюсь преобразовать, таковы:

struct{
BYTE                           byEnable;
BYTE                           byRes1[3];
DWORD                          dwTriggerType;
NET_ITC_TRIGGER_PARAM_UNION    uTriggerParam;
BYTE                           byRes[64];
}NET_ITC_SINGLE_TRIGGERCFG,*LPNET_ITC_SINGLE_TRIGGERCFG;

union{
DWORD                              uLen[1070];
NET_ITC_POST_IOSPEED_PARAM         struIOSpeed;
NET_ITC_POST_SINGLEIO_PARAM        struSingleIO;
NET_ITC_POST_RS485_PARAM           struPostRs485;
NET_ITC_POST_RS485_RADAR_PARAM     struPostRadar;
NET_ITC_POST_VTCOIL_PARAM          struVtCoil;
NET_ITC_EPOLICE_IOTL_PARAM         struIOTL;
NET_ITC_EPOLICE_RS485_PARAM        struEpoliceRs485;
NET_ITC_EPOLICE_RS485_PARAM        struPERs485;
}NET_ITC_TRIGGER_PARAM_UNION,*LPNET_ITC_TRIGGER_PARAM_UNION;

Я пробовал следующее:

  PNetItcSingleTriggerCfg = ^TNetItcSingleTriggerCfg;
TNetItcSingleTriggerCfg = record
byEnable:      Byte;
byRes1:        array [0..2] of Byte;
dwTriggerType: DWord;
uTriggerParam: TNetItcTriggerParamUnion;
byRes:         array [0..63] of Byte;
end;

PNetItcTriggerParamUnion = ^TNetItcTriggerParamUnion;
TNetItcTriggerParamUnion = record
case integer of
0: (uLen:             array [0..1069] of DWord);
1: (struIOSpeed:      TNetItcPostIOSpeedParam);
2: (struSingleIO:     TNetItcPostSingleIOParam);
3: (struPostRs485:    TNetItcPostRS485Param);
4: (struPostRadar:    TNetItcPostRS485RadarParam);
5: (struVtCoil:       TNetItcPostVTCoilParam);
6: (struHvt:          TNetItcPostHvtParam);
7: (struIOTL:         TNetItcEPoliceIOTLParam);
8: (struEpoliceRs485: TNetItcEPoliceRS485Param);
9: (struPERs485:      TNetItcEPoliceRS485Param);
10:(struPostMpr:      TNetItcPostMprParam);
11:(struViaVtCoil:    TNetDvrViaVtCoilParam);
12:(struPostImt:      TNetItcPostImtParam);
13:(struPostPrs:      TNetItcPostPrsParam);
14:(struIpcHvt:       TNetIpcPostHvtParam);
15:(struHvtV50:       TNetIpcPostHvtParamV50);
end;

И я также попытался использовать его как вложенную запись (как предложено здесь http://rvelthuis.de/articles/articles-convert.html#unions )

  PNetItcSingleTriggerCfg = ^TNetItcSingleTriggerCfg;
TNetItcSingleTriggerCfg = record
byEnable:      Byte;
byRes1:        array [0..2] of Byte;
dwTriggerType: DWord;
uTriggerParam: record
case integer of
0: (uLen:             array [0..1069] of DWord);
1: (struIOSpeed:      TNetItcPostIOSpeedParam);
2: (struSingleIO:     TNetItcPostSingleIOParam);
3: (struPostRs485:    TNetItcPostRS485Param);
4: (struPostRadar:    TNetItcPostRS485RadarParam);
5: (struVtCoil:       TNetItcPostVTCoilParam);
6: (struHvt:          TNetItcPostHvtParam);
7: (struIOTL:         TNetItcSingleIOTLParam);
8: (struEpoliceRs485: TNetItcEPoliceRS485Param);
9: (struPERs485:      TNetItcEPoliceRS485Param);
10:(struPostMpr:      TNetItcPostMprParam);
11:(struViaVtCoil:    TNetDvrViaVtCoilParam);
12:(struPostImt:      TNetItcPostImtParam);
13:(struPostPrs:      TNetItcPostPrsParam);
14:(struIpcHvt:       TNetIpcPostHvtParam);
15:(struHvtV50:       TNetIpcPostHvtParamV50);
end;
byRes:         array [0..63] of Byte;
end;

Я видел подобные вопросы здесь (т.е. Как мне перевести C union в Delphi? ), но объединение в моем примере находится в середине структуры, и, как я понимаю, «конец» оператора case также заканчивает запись.

Я думаю, что понимаю теорию, лежащую в основе записи варианта, имеющей одинаковое распределение памяти для полей в выражении case, поэтому используемые поля будут либо / или, но я не могу понять, как определить, как DLL обращается к эти записи, будь то struName.unionName.fieldName или struName.fieldName, а также способ определения объединения (т. е. что такое селектор оператора case и как узнать, какой тип данных это селектор).

У меня есть три аналогичные структуры для перевода, и я думаю, что если я смогу взломать одну, я смогу взломать их все.

С записями, как описано выше, я получаю сообщение об ошибке error Ошибка параметра. Входной или выходной параметр в API SDK имеет значение NULL при вызове функции из DLL (если вам нужна дополнительная информация об этом, пожалуйста, спросите), что заставляет меня думать, что мои записи не были преобразованы правильно.

Я использую HCNetSDK.dll SDK версии 5.0.3.20, и моя IDE — XE7, если это помогает.

Любая помощь будет оценена.

9

Решение

Если предположить, что настройки выравнивания структуры совпадают, то обе ваши попытки конвертировать объединение верны. Вы можете использовать тот, который вы предпочитаете. Для чего бы это ни стоило, я бы предпочел первый подход, когда вы объявляете тип для представления объединения.

Какова бы ни была ваша настоящая проблема, она, похоже, не связана с конверсионным объединением. Простой способ проверить это — проверить, совпадают ли размеры типов в версиях C ++ и Delphi и совпадают ли смещения для каждого члена.

Для теста используйте размер шрифта sizeof в C ++ и SizeOf в Дельфи. Для смещений используйте offsetof макрос для C ++ и трюк, показанный в мой ответ здесь для Delphi.

6

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]