Я знаю, что об этом уже спрашивали, но я безуспешно пытаюсь преобразовать некоторые структуры / объединения 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, если это помогает.
Любая помощь будет оценена.
Если предположить, что настройки выравнивания структуры совпадают, то обе ваши попытки конвертировать объединение верны. Вы можете использовать тот, который вы предпочитаете. Для чего бы это ни стоило, я бы предпочел первый подход, когда вы объявляете тип для представления объединения.
Какова бы ни была ваша настоящая проблема, она, похоже, не связана с конверсионным объединением. Простой способ проверить это — проверить, совпадают ли размеры типов в версиях C ++ и Delphi и совпадают ли смещения для каждого члена.
Для теста используйте размер шрифта sizeof
в C ++ и SizeOf
в Дельфи. Для смещений используйте offsetof
макрос для C ++ и трюк, показанный в мой ответ здесь для Delphi.
Других решений пока нет …