Skip to content

How do I use complex data structures with ffi, ref-struct, and ref-array? #28

@zacharyabresch

Description

@zacharyabresch

Using Complex Data Structures with ffi, ref-struct, and ref-array

I am working on a project that uses ffi to interact with a compiled C library. I am trying to get some complex data structures to work and am having problems figuring out the proper way to get values inside these data structures. I have two instances I'm trying to figure out. I am not a C guy so I'm winging it on that end.

Instance 1

There is a C struct that contains properties that are, what look like pointers to character arrays. Here's the C-code that defines the struct:

#define RPC_STRING_LENGTH           32
#define RPC_STRING_LENGTH_CALLID    128
typedef struct {
    E_CALL_STATE eCallState;
    BOOL bInboundCall;
    BOOL bVideoCall;
    BOOL bRecording;
    BOOL bEncrypted;
    BOOL bHDAudio;
    BOOL bVirtualMeetingCall;
    E_PROTOCOL_CODEC eCurrentCodec;
    E_PROTOCOL_ALERT_INFO_CALL_TYPE eAlertInfoType;
    double dAccumulatedMOSLQ;
    int  nVideoState;
    int  nErrorCode;
    unsigned int nCallStartTime;
    char cPhoneNumber[RPC_STRING_LENGTH];
    char cName[RPC_STRING_LENGTH];
    char cCallId[RPC_STRING_LENGTH_CALLID];
    char cPreviousCallId[RPC_STRING_LENGTH_CALLID];
} RPC_CALL_STATE;

Now, I've been able to successfully extract the E_CALL_STATE value and the BOOL properties but I'm having difficulty getting the strings stores in cPhoneNumber, cName, cCallId, and cPreviousCallId. Here's how I have the it setup using ref-struct:

import ref from 'ref';
import StructType from 'ref-struct';

const RPC_CALL_STATE = StructType({
    eCallState: ref.types.int,
    bInboundCall: ref.types.bool,
    bVideoCall: ref.types.bool,
    bRecording: ref.types.bool,
    bEncrypted: ref.types.bool,
    bHDAudio: ref.types.bool,
    bVirtualMeetingCall: ref.types.bool,
    dAccumulatedMOSLQ: ref.types.double,
    nVideoState: ref.types.int,
    nErrorCode: ref.types.int,
    nCallStartTime: ref.types.uint,
    cPhoneNumber: ref.types.char,
    cName: ref.types.char,
    cCallId: ref.types.char,
    cPreviousCallId: ref.types.char,
});

Here's the Javascript that interprets this struct (for reference, RPC_CALL_STATE is an externally defined enum):

pDataRef = ref.reinterpret(pData, RPC_CALL_STATE.size);
pDataRef.type = RPC_CALL_STATE;
const callProgressStruct = ref.get(pDataRef);

If I look at the value stored on callProgressStruct.cPhoneNumber, I get 0. So, a few questions:

  • What is the correct ref.types to use here?
    • Is char correct?
    • If not, what should this be?
  • How do I extract the actual string value stored in cPhoneNumber?
  • Is there a way to use ref-array here?

Instance 2

I have a C struct that is defined as such:

typedef struct AUDIO_OS_DEVICES {
    int nNumberDevices;
    AUDIO_OS_DEVICE *pDevices;
} AUDIO_OS_DEVICES;

In this code, *pDevices ends up being an array of AUDIO_OS_DEVICE structs. Those structs are defined in C as:

typedef struct AUDIO_OS_DEVICE {
    int deviceId;
    int deviceFlags;
    char deviceName[AUDIO_OS_DEVICE_NAME_MAX_LEN];
    char deviceUID[AUDIO_OS_DEVICE_UID_MAX_LEN];
    char manufacturerName[AUDIO_OS_DEVICE_MANUFACTURER_MAX_LEN];
} AUDIO_OS_DEVICE;

In Javascript I have this setup using ref-struct:

const AUDIO_OS_DEVICE = StructType({
  deviceId: ref.types.int,
  deviceFlags: ref.types.int,
  deviceName: ref.types.char,
  deviceUID: ref.types.char,
  manufacturerName: ref.types.char,
});

const AUDIO_OS_DEVICES = StructType({
    nNumberDevices: ref.types.int,
    pDevices: [???],
});

I have no idea what type to cast pDevices to here nor do I know how to extract the array of AUDIO_OS_DEVICE structs. I am also hitting the issue already described with character arrays.

Any help would be appreciated. I'm at a dead-end until I can figure this out.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions