Node.js FFI调用irApiSA.dll的irSAInitialize函数失败求助
Let's break down why your irSAInitialize call is returning failure (0) while irUnInitialize works, and fix the issues step by step.
Key Discrepancies Between Your Node.js Code and Working C# Implementation
Looking at your C# code and the C header file, there are three critical mismatches that are almost certainly causing the failure:
1. Calling Convention Mismatch
Your C# code explicitly uses CallingConvention.Cdecl for the DLL import, but Node.js FFI defaults to stdcall on Windows. If the DLL's irSAInitialize function is compiled with Cdecl (which matches your C# setup), using the wrong calling convention will corrupt the stack during parameter passing, leading to unexpected failures.
2. Handle Type Mismatch
The C header defines IR_HANDLE as long, but your C# code uses ref int for the handle parameter. This tells us that in practice, the DLL expects a 32-bit integer pointer for the handle, not a 64-bit long. Your Node.js code uses ref.refType('long'), which creates a pointer to an 8-byte value—this mismatch will prevent the DLL from writing a valid handle to your output variable.
3. String Parameter Handling
Your C# code passes initialized 256-character buffers for all string parameters, while your Node.js code passes empty strings (""). Some DLLs require non-null, properly sized buffers for string parameters (even if they're empty) to pass validation checks, rather than a pointer to an empty string literal.
Fixed Node.js Code Implementation
Here's the revised code addressing all three issues:
const ffi = require('ffi'); const ref = require('ref'); // Match C#'s ref int: use pointer to 32-bit int instead of long const intPtr = ref.refType('int'); const dllPath = "O:\\ApiBin\\"; const dllFile = dllPath + "irApiSA.dll"; // Critical: Specify Cdecl calling convention to match C# and DLL const randConnect = ffi.Library(dllFile, { 'irSAInitialize': ['int', ['pointer', 'pointer', 'pointer', 'pointer', 'pointer', 'pointer', intPtr]], 'irUnInitialize': ['int', []] }, { callingConvention: 'cdecl' }); // Mimic C#'s 256-char empty buffer for string parameters function createEmptyBuffer(size = 256) { return Buffer.alloc(size, 0); // Initialize with null bytes } // Create buffers for all 6 string parameters const bufA = createEmptyBuffer(); const bufB = createEmptyBuffer(); const bufC = createEmptyBuffer(); const bufD = createEmptyBuffer(); const bufE = createEmptyBuffer(); const bufF = createEmptyBuffer(); // Allocate handle output variable (32-bit int) const handleOut = ref.alloc('int'); // Call initialize function const initResult = randConnect.irSAInitialize(bufA, bufB, bufC, bufD, bufE, bufF, handleOut); console.log("Init Result: " + initResult); const handle = handleOut.deref(); console.log("Init Handle: " + handle); // Call uninitialize (should still work if setup is correct) const uninitResult = randConnect.irUnInitialize(); console.log("Uninit Result: " + uninitResult);
Additional Troubleshooting Tips
If the above fixes don't resolve the issue, check these common pitfalls:
- DLL Architecture Match: Ensure your Node.js runtime is the same bitness (32/64-bit) as the
irApiSA.dll. A 64-bit Node.js can't properly load and call a 32-bit DLL, and vice versa. - Dependency Files:
irSAInitializemay require additional configuration files or dependent DLLs thatirUnInitializedoesn't. Verify all required files are in the same directory asirApiSA.dllor in your system PATH. - Parameter Values: Double-check if any of the string parameters require valid file paths (even default ones). Your C# code uses empty buffers, but maybe the DLL expects specific paths in some environments—consult the DLL's documentation for parameter requirements.
内容的提问来源于stack exchange,提问作者iDurocher

