I have a dll with the following function signatures (Delphi):
function OpenDataFile(FileName: PChar): int32;
procedure CloseDataFile(Handle: int32);
where OpenDataFile should return a value >= 0 on success.
In python this works great:
import ctypes
dll = ctypes.WinDLL("readfile.dll")
fhandle = dll.OpenDataFile(r"C:\Users\okapi210\files\test.file")
print(fhandle)
dll.CloseDataFile()
returns 0
However in nim I can't seem to get things working properly:
proc OpenDataFile(filename: cstring): cint {.stdcall, dynlib: "readfile.dll", importc.}
proc CloseDataFile(handle: cint) {.stdcall, dynlib: "readfile.dll", importc.}
var fhandle = OpenDataFile(r"C:\Users\okapi210\files\test.file")
echo fhandle
CloseDataFile(fhandle)
returns -1001
nim compiler info:
Nim Compiler Version 0.20.0 [Windows: amd64]
Compiled at 2019-06-06
Copyright (c) 2006-2019 by Andreas Rumpf
git hash: e7471cebae2a404f3e4239f199f5a0c422484aac
active boot switches: -d:release
same result with both gcc and vcc
Delphi defaults to a register calling convention that the C compilers usually don't support. You need to use
function OpenDataFile(FileName: PChar): int32; stdcall;
procedure CloseDataFile(Handle: int32); stdcall;
Yeah I jumped the gun... after some further testing it was just luck python was returning a 0. @Araq it's a closed source dll to make this even more annoying, but the functions are being exported as stdcall as far as I've been told.
I set up this test. Delphi dll code:
library wrapd;
uses
System.SysUtils;
{$R *.res}
function OpenDataFile(FileName: PChar): int32; stdcall;
begin
WriteLn(FileName);
WriteLn('test test test');
Result := 99;
end;
exports OpenDataFile;
end.
nim code:
proc OpenDataFile(filename: cstring): int32 {.stdcall, dynlib: "wrapd.dll", importc.}
let fpath: cstring = r"C:\Users\okapi210\Desktop\test.file"
var fhandle = OpenDataFile(fpath)
echo fhandle
result:
?????????????????e
test test test
99
So passing a cstring to PChar isn't working I probably just need a byte array