Monthly Archives: November 2016

Wrapping stdcall functions in Node FFI

A colleague of mine needed help wrapping some C DLLs for NodeJS. He’s using the Node FFI API for the wrapping, which unfortunately is a little light on documentation. The problem was that by default Node FFI wraps cdecl functions and there is no mention of stdcall anywhere. In fact the consensus on the net seems to be that it’s not possible at all. Reading the sources proved more fruitful and so I document the way here for future generations to find:

The standard way of initializing a FFI wrapper using the array in the constructor

actually takes an additional parameter with the calling convention, but in stdcall the function names are often decorated with an additional “@x” which denotes the bytes the function parameters need on the stack. Problem is, blah@x is not a valid identifier and in the array the Javascript function pointer always has the same name as the function in the DLL. The solution is to manually wrap the functions, which I actually prefer anyway as the function pointer doesn’t end in a struct but can be used directly afterwards:

The resulting wrapper is called using “AdsPortOpen()” and it accesses the function with the decorated name “_AdsPortOpen@0”. The easiest way to get the decorated name is using the dumpbin utility from Visual Studio with the “/exports” parameter:

<br />
C:\Windows\System32&gt;dumpbin /exports gdi32.dll<br />
Microsoft (R) COFF/PE Dumper Version 10.00.40219.01<br />
Copyright (C) Microsoft Corporation.  All rights reserved.</p>
<p>Dump of file gdi32.dll</p>
<p>File Type: DLL</p>
<p>  Section contains the following exports for GDI32.dll</p>
<p>    00000000 characteristics<br />
    573C8294 time date stamp Wed May 18 16:56:20 2016<br />
        0.00 version<br />
        1000 ordinal base<br />
         727 number of functions<br />
         715 number of names</p>
<p>    ordinal hint RVA      name</p>
<p>       1012    0 00043F40 AbortDoc = _AbortDoc@4<br />
       1013    1 00045806 AbortPath = _AbortPath@4<br />
       1014    2 0003BA5C AddFontMemResourceEx = _AddFontMemResourceEx@16<br />
[...]