4
votes

I have a legacy Delphi dll which requires a json string as input (pAnsiChar) and returns an int as success or failure. I have managed to connect to the dll from nodejs using node-ffi. However, i am getting return int value points to invalid json string.

Could someone point me in the direction as to how to call a Delphi dll with pAnsiChar as function arguments from node

Thanks

3
What about calling convention? My research seems to indicate the node ffi requires cdecl. Do you know different?David Heffernan
This dll uses stdcall and i can connect to it from other languages such as vba etc. And now i can connect to the dll via node-ffi calls return a value for some functions and was not able to do that on a function that takes json string as PAnsiChar param and returns a json string to a passed PAnsiChar pointeruser3234437
I understand that the DLL exports stdcall functions. My belief is that node-ffi can only call cdecl functions. You accepted Remy's answer which leads me to believe that you have extra information about node-ffi that informs you that node-ffi can in fact call stdcall functions. I suppose it is plausible that node-ffi could add some extra code to detect whether or not the callee tidied up the stack and adapt accordingly. What information do you have?David Heffernan
You seem to be missing my point. As I understand it, node-ffi only supports cdecl. Your function is stdcall. I presume you read my answer explaining that. You accepted Remy's without commenting on mine. Which I can only assume means that you have information that says that node-ffi supports stdcall.David Heffernan
This is the VBA code Declare Function JSCall Lib "NETCDFLIB.DLL" (ByVal Req As String, ByVal RetBuf As String, ByVal RetBufLen As Long) As Long and according to the doco i have, it is a stdcall dll. This dll is used to extract NetCDF data in json format. Unfortunately, in my original email i failed to indicate that it is a stdcall dll and infact, i thought nodejs can only call stdcall dlls only on windows hence not mentioning. Having said that, i was able to get function return call (an int value) which indicated that the req string passed to the dll was invalid jscall hence call for help.user3234437

3 Answers

4
votes

PAnsiChar in Delphi is a char* in C/C++. In the FFI declaration for the DLL function, simply declare the PAnsiChar parameter as a "string", which is a null-terminated char* in FFI.

For example, given this Delphi function:

function ProcessJson(Json: PAnsiChar): Integer; stdcall;

The node.js code would look something like this:

var ffi = require('ffi');

var mydll = ffi.Library('mydll', {
  'ProcessJson': [ 'int', [ 'string' ] ]
});

var ret = mydll.ProcessJson("json content here");
5
votes

So far as I can tell, Node FFI does not currently allow you to control the calling convention. And the default is cdecl. So on the Delphi side it looks like this:

function MyFunction(str: PAnsiChar): Integer; cdecl;

On the node-ffi side I think it looks like this:

var ffi = require('ffi');
var mylib = ffi.Library('libname', {
  'MyFunction': [ 'int', [ 'string' ] ]
});
var retval = mylib.MyFunction("some string");

If you cannot modify the legacy DLL then I'm afraid that you may need to wrap it in a DLL that does nothing other than export cdecl functions, and then pass them through to the legacy DLL's stdcall functions.

0
votes

I'm looking into this myself, and based on the research I've done node-ffi can handle the following calling conventions:

thiscall, fastcall and MSVC cdecl on Windows

Per the changelog in the readme.

This isn't the best source of information, but there is no mention of stdcall in the readme. fastcall is supported though, which is also a callee clean-up calling convention, so it may be best to switch your functions to fastcall instead of cdecl if you're looking to call a Delphi DLL with node-ffi.

I'll try calling some simple StdCall functions through node-ffi to see if it can handle them properly and check back here once I have some results.