在python中的Delphi上使用DLL

时间:2019-04-19 21:28:30

标签: python delphi dll ctypes python-3.4

我正在尝试使用以下签名(更多:http://www.lawlabs.ru/parser_address.htm)在python 3.4中从dll调用函数:

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;

我认为语法是Delphi,在将ctypes用于此签名时会出错。

我对delphi和ctypes类型的预期匹配:

String -> c_char_p  
ShortString -> c_char_p  
var String -> POINTER(c_char_p)  
boolean -> c_bool  

因此,Python中的函数签名(其中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    

但是,此签名出现错误。

尝试传递参数:

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)

完整的错误代码是:

OSError: exception: access violation reading 0x00000001

有趣的是,当将第一个布尔参数替换为False时,我们有

OSError error: exception: access violation reading 0x00000000

当您尝试通过引用传递布尔参数时,随机地址会发生错误

如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

您是对的:那就是Delphi(或FreePascal),这就是问题所在。

恐怕编写DLL的人没有想到其他语言如何使用DLL。它们导出带有特定于Delphi的参数的函数,例如stringShortString,这些只能由具有与DLL相同的共享内存管理器的Delphi或C ++ Builder 使用,甚至不是所有这些版本。

因此,您将无法直接使用DLL ,不能使用C,也不能使用 ctypes String不会映射到c_char_p不同类型的ShortString等也不会映射。唯一匹配的类型是c_bool,但不会不会让你走的很远。

您可以与DLL的作者进行交谈,并告诉他们阅读我的文章,该文章也介绍了如何编写可被其他语言使用的DLL:DLLs dos and don'ts

或者您可以找到有人使用Delphi或C ++ Bulder为DLL写一个包装程序,该程序包装函数并将特定于Delphi的类型转换为与C兼容的类型,例如char *({{ 1}})或PAnsiCharwchar_t *)。

我无法阅读您链接到的页面,所以我不知道您是否有权访问源代码。如果是这样,您可以尝试找人更改出口,以便可以直接从C使用出口。那么您将不需要包装器。


FWIW,这些类型也可以在FreePascal中找到,但是那里也会有同样的问题。解决方案也一样。