I have a simple DLL written in Delphi 10.4. When I call the DLL from another Delphi application, everything works 100%, but when I call the same DLL from a Java application (using JNA) I get strange results.
I initially declared my DLL input parameters of type PChar. When I call the DLL from the Java app, I get funny characters inside my DLL. I changed it to ShortString, but then I loose the first character of the string in my DLL. I probably need to do some datatype casting in Java but I cannot find out what. Can somebody perhaps help?
Here is a sample DLL in Delphi to demonstrate:
procedure TestDataTypes(PCharVar: PChar; ShortStringVar: ShortString); stdcall;
begin
ShowMessage('PChar: ' + PCharVar + #13#10 +
'ShortString: ' + ShortStringVar);
end;
exports
TestDataTypes;
Code to call DLL from Delphi:
procedure TestDataTypes(PCharVar: PChar; ShortStringVar: ShortString); stdcall; external 'TestDataType.dll';
...
TestDataTypes(PChar('PChar Value'), 'ShortString Value');
Code to call DLL from Java:
INSTANCE.TestDataTypes("Java PChar Value", "Java ShortString Value");
Results: Top is when DLL is called from Delphi and bottom when it is called from Java:
Some Feedback: I changed the datatype in Delphi to PAnsiChar and it works on my local pc. When deployed, it worked on some client machines but not others. The error I get when I call the DLL from my Java app is "Invalid memory access". I have added logging in my DLL and it seems it does not even enter the DLL.... I have also changed the Java datatype to WString but that did not make a difference.
Delphi code:
function HasCOMConnection(COMServerName: PAnsiChar): Boolean; stdcall;
begin
WriteLog('HasCOMConnection: 64-Bit DLL entered');
Result := HasConnection(COMServerName);
end;
Java Call:
private interface IPMOProcessLabResult extends com.sun.jna.Library {
boolean HasCOMConnection(String COMServerName);
}
private boolean canConnectToCOMServer() {
try {
IPMOProcessLabResult lib = (IPMOProcessLabResult) Native.loadLibrary(config.libraryName, IPMOProcessLabResult.class);
return lib.HasCOMConnection(config.comServerName);
}
catch (Exception ex) {
new AppendLog(new Date(), this.getClass() + "\t" + ex.getClass() + "\t" + "Exception while trying to connect to COMServer: " + ex.getMessage(), "debug");
return false;
}
}
PChar
is only an alias, which was changed to PWideChar
with Delphi 2009 (let's just say, standard string and character types were changed to Unicode
)! So every character does now use 2 Bytes.
So in order to make your DLL working as it should, you should change PChar
to PAnsiChar
.
Or you have to make some changes to your Java app so it does use some two-byte-character type. But I have no Java experience, so I can't help you with that.
And forget about shortstring, this type is not compatible to other languages!
See this site for more references about how to use and not to use DLLs.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments