I'm trying to call a function from dll in python 3.4 with the following signature (more: http://www.lawlabs.ru/parser_address.htm):
function GetAddressFields(
AddressStr: String;
var FullStr: String;
var QualifiedStr: String;
Separator: ShortString = #13#10;
IsRussia: Boolean = True;
WithDescription: Boolean = True;
WithExceptions: Boolean = True;
LastIsHome: Boolean = True;
Subject: Boolean = True;
WithUnrecognized: Boolean = True): String;
I think syntax is Delphi and get an error when using ctypes for this signature.
My expected match for delphi and ctypes types:
String -> c_char_p
ShortString -> c_char_p
var String -> POINTER(c_char_p)
boolean -> c_bool
Therefore the function signature in Python (where dll = windll.LoadLibrary(...)):
dll.GetAddressFields.argtypes = (
c_char_p,
POINTER (c_char_p),
POINTER (c_char_p),
c_char_p,
c_bool,
c_bool,
c_bool,
c_bool,
c_bool,
c_bool)
dll.GetAddressFields.restype = c_char_p
However, an error occurs with this signature.
Attempt to pass parameters:
param_1 = c_char_p("".encode("ascii"))
param_2 = c_char_p("".encode("ascii"))
result = dll.GetAddressFields(
c_char_p('test'.encode("ascii")),
byref(param_1),
byref(param_2),
c_char_p("\r\n".encode("ascii")),
True,
True,
True,
True,
True,
True)
The complete error code is:
OSError: exception: access violation reading 0x00000001
Interestingly, when replacing the first boolean parameter with False, we have
OSError error: exception: access violation reading 0x00000000
When you try to pass boolean parameters by reference, an error occurs with random addresses
How solve this problem?
You are right: that is Delphi (or FreePascal), and that is the problem.
I'm afraid the people who wrote the DLL didn't think about how the DLL could be used by other languages. They export functions with Delphi-specific arguments like string
and ShortString
, that can only be used by Delphi or C++Builder with the same shared memory manager as the DLL, and not even by all versions of these.
So you won't be able to use the DLL directly, not using C and not using ctypes. String
does not map to c_char_p
, nor does the different type ShortString
, etc. The only type that matches is c_bool
, but that won't get you very far.
You could talk to the authors of the DLL and tell them to read my article on how to write a DLL that can be used by other languages too: DLLs dos and don'ts.
Or you could find someone who writes a wrapper for the DLL, either using Delphi or C++Bulder, that wraps the functions and converts the Delphi-specific types to C-compatible types like char *
(PAnsiChar
) or wchar_t *
(PWideChar
).
I can't read the page you linked to, so I don't know if you have access to the source code. If so, you could try to find someone who changes the exports so that they are directly usable from C. Then you would not need a wrapper.
FWIW, these types can also be found in FreePascal, but there you'd have the same problem. The solution would be the same, too.
User contributions licensed under CC BY-SA 3.0