How to proper working with Union and Sctruct nested
ozguracar opened this issue · comments
Özgür Acar commented
I´m trying to create some types that will be used with node-ffi, but I have some doubts about how to use Union and Struct type nested.
Should I define first the nested fields as new types, or can I does directly like this:
union _error {
BYTE byte;
struct
{
BYTE memoryFull : 1;
BYTE extEpromError : 1;
BYTE intEpromError : 1;
BYTE rtcError : 1;
BYTE romError : 1;
BYTE batteryEmpty : 1;
BYTE : 1;
BYTE : 1;
};
};
union _otomatStatus {
BYTE byte;
struct
{
BYTE sended : 1;
BYTE received : 1;
BYTE tickedReduced : 1;
BYTE tickedFinished : 1;
BYTE : 1;
BYTE : 1;
BYTE : 1;
BYTE : 1;
};
};
struct _H_status
{
union {
BYTE block[32];
struct
{
BYTE day;
BYTE month;
BYTE year;
BYTE hour;
BYTE minute;
BYTE second;
_error error;
BYTE state;
int recordCount;
union {
DWORD status;
struct
{
BYTE relay0 : 1;
BYTE relay1 : 1;
BYTE relay2 : 1;
BYTE relay3 : 1;
BYTE cardOperationCont : 1;
BYTE newCard : 1;
BYTE taskEnable : 1;
BYTE relaxMode : 1;
BYTE redLed : 1;
BYTE greenLed : 1;
BYTE blueLed : 1;
BYTE accessValue : 1;
BYTE accessReady : 1;
BYTE : 1;
BYTE : 1;
BYTE : 1;
BYTE input0 : 1;
BYTE input1 : 1;
BYTE : 1;
BYTE : 1;
BYTE : 1;
BYTE : 1;
BYTE cardWriteOperation : 1;
BYTE cardWriteResult : 1;
BYTE battery : 4;
BYTE registerMode : 1;
BYTE menuMode : 1;
BYTE deviceNotWorkingTime : 1;
BYTE lastPowerType : 1;
};
};
int cardCode;
WORD accessCode;
BYTE appIndex;
BYTE cardMsgNo;
BYTE inOut;
int totalCredit;
_otomatStatus otomatStatus[3];
};
};
};
#####################################3
var ffi = require('ffi')
var ref = require('ref')
var StructType = require('ref-struct')
var UnionType = require('ref-union')
var deviceSerial = 0xC8CC3FB
var devicePass = 0xA25E8AD0
var deviceIP = 0x2801A8C0
var devicePORT = 0x1592
var BYTE = ref.types.uint8
var WORD = ref.types.uint16
var DWORD = ref.types.uint32
var INT = ref.types.int
var BOOL = ref.types.bool
var UIDPtr = ref.refType('uint32');
var union = UnionType({
"byte": BYTE,
"s": StructType({
"memoryFull": BYTE,
"extEpromError": BYTE,
"intEpromError": BYTE,
"rtcError": BYTE,
"romError": BYTE,
"batteryEmpty": BYTE,
"c": BYTE,
"d": BYTE,
})
})
var otomat = UnionType({
"byte": BYTE,
"s": StructType({
"sended": BYTE,
"received": BYTE,
"tickedReduced": BYTE,
"tickedFinished": BYTE,
"a": BYTE,
"b": BYTE,
"c": BYTE,
"d": BYTE,
})
})
var HStruct = StructType({
"un": UnionType({
"block": BYTE,
"h": StructType({
"day": BYTE,
"month": BYTE,
"year": BYTE,
"hour": BYTE,
"minute": BYTE,
"second": BYTE,
"_error": union,
"state": BYTE,
"recordCount": INT,
"status": UnionType({
"status": DWORD,
"s": StructType({
"relay0": BYTE,
"relay1": BYTE,
"relay2": BYTE,
"relay3": BYTE,
"cardOperationCont": BYTE,
"newCard": BYTE,
"taskEnable": BYTE,
"relaxMode": BYTE,
"redLed": BYTE,
"greenLed": BYTE,
"blueLed": BYTE,
"accessValue": BYTE,
"accessReady": BYTE,
"a": BYTE,
"b": BYTE,
"c": BYTE,
"input0": BYTE,
"input1": BYTE,
"d": BYTE,
"e": BYTE,
"f": BYTE,
"g": BYTE,
"cardWriteOperation": BYTE,
"cardWriteResult": BYTE,
"battery": BYTE,
"registerMode": BYTE,
"menuMode": BYTE,
"deviceNotWorkingTime": BYTE,
"lastPowerType": BYTE
})
}),
"cardCode": INT,
"accessCode": WORD,
"appIndex": BYTE,
"cardMsgNo": BYTE,
"inOut": BYTE,
"totalCredit": INT,
"_otomatStatus": otomat
})
})
})
var status = new HStruct
var sdk = ffi.Library('./_RC_UTIL.dll', {
'__Get_Status': [INT, [DWORD, DWORD, DWORD, WORD, BOOL, "pointer"]],
'__Get_Card_UID_Readed': [INT, [DWORD, DWORD, DWORD, WORD, UIDPtr]],
'__Device_Resume': [INT, [DWORD, DWORD, DWORD, WORD]],
'__Device_Finish': [INT, [DWORD, DWORD, DWORD, WORD, "pointer"]],
'__Set_Led_Color': [INT, [DWORD, DWORD, DWORD, WORD, BYTE, BOOL, "pointer"]],
'__Clear_Memory': [INT, [DWORD, DWORD, DWORD, WORD]],
})
sdk.__Set_Led_Color(deviceSerial, devicePass, deviceIP, devicePORT, 8, true, status.ref())
sdk.__Get_Status(deviceSerial, devicePass, deviceIP, devicePORT, true, status.ref())
console.log(status)
var outUID = ref.alloc('uint32');
sdk.__Get_Card_UID_Readed(deviceSerial, devicePass, deviceIP, devicePORT, outUID);
sdk.__Device_Resume(deviceSerial, devicePass, deviceIP, devicePORT);
sdk.__Device_Finish(deviceSerial, devicePass, deviceIP, devicePORT, status.ref());
var actualNumber = outUID.deref();
console.log(actualNumber)
console.log(outUID)
Kevin Ley commented
For me, nested StructTypes don't work either.
const someNestedStruct = StructType({
someThing: StructType({
somePorperty: ref.types.float,
}),
otherThing: StructType({
someProperty: ref.types.float,
})
});
AssertionError [ERR_ASSERTION]: Unknonwn type: StructType