在 python 中在 Delphi 上使用 DLL

弗拉基米尔·维克托罗维奇

我正在尝试从具有以下签名的 python 3.4 中的 dll 调用函数(更多: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;

我认为语法是 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

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

如何解决这个问题?

鲁迪·维尔休斯

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

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

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

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

或者,您可以找到使用 Delphi 或 C++Bulder 为 DLL 编写包装器的人,该包装器包装函数并将 Delphi 特定类型转换为 C 兼容类型,如char *( PAnsiChar) 或wchar_t *( PWideChar)。

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


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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章