如何在Node.js侧打印以PVoidArray传入的结构体数组?
Got it, let's break this down step by step. Since you're working with ffi, ref, and your pre-compiled libfun.so library, and want to print struct array elements passed as a PVoidArray without defining a dedicated struct array type, here's how to start with accessing and printing myArray[0]:
Prerequisite: Mirror Your C Struct in Node.js
First, you need to replicate your C struct from fun.h using ref — this lets Node.js correctly interpret the raw memory behind the void* pointers. For example, if your C struct looks like this:
// fun.h typedef struct { int id; char name[20]; double value; } Data;
Your Node.js struct definition would be:
const ref = require('ref'); const ffi = require('ffi-napi'); // Use ffi-napi for better Node.js compatibility, or raw ffi if you prefer // Define the struct matching your C Data type const DataStruct = ref.types.Struct({ id: ref.types.int, name: ref.types.char.array(20), // Match fixed-length char array from C value: ref.types.double }); // Create a pointer type for your struct const DataPointer = ref.refType(DataStruct);
Load Your Library and Access myArray[0]
Assuming you've already loaded libfun.so and have access to the myArray (a PVoidArray, which is essentially a void** in C), here's how to extract and print the first element:
// Load your library (adjust function signatures to match your actual C exports) const libfun = ffi.Library('./libfun.so', { // Example: if your C function accepts the PVoidArray and its length processMyArray: ['void', ['pointer', 'int']] }); // Assume myArray is the PVoidArray you're working with (passed in or returned from a C function) // Step 1: Read the first void* from the array (offset 0, since each pointer takes ref.sizeof.pointer bytes) const firstVoidPtr = ref.readPointer(myArray, 0); // Step 2: Cast the void* to your struct pointer type const firstDataPtr = firstVoidPtr.cast(DataPointer); // Step 3: Dereference the pointer to get the actual struct instance const firstData = firstDataPtr.deref(); // Step 4: Print the struct fields (adjust based on your actual struct members) console.log('First element in the PVoidArray:'); console.log(`ID: ${firstData.id}`); // For fixed-length char arrays, convert to a JS string manually console.log(`Name: ${ref.readCString(firstData.name, 0)}`); console.log(`Value: ${firstData.value}`);
Key Notes to Remember
- Memory Safety: If the
PVoidArrayor structs it points to are allocated in C, use cleanup functions fromlibfun.soto free memory and avoid leaks. - Dynamic Strings: If your struct uses a
char*(dynamic string) instead of a fixed array, you can directly accessfirstData.nameas a JS string (refhandles CString conversion automatically). - Accessing Later Elements: For
myArray[1], increment the offset byref.sizeof.pointer(e.g.,ref.readPointer(myArray, ref.sizeof.pointer)).
内容的提问来源于stack exchange,提问作者user9078927

