我试图从python3.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类型匹配:
^{pr2}$因此,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),这就是问题所在。在
恐怕写动态链接库的人并没有想到这个动态链接库可以被其他语言使用。它们导出带有Delphi特定参数的函数,例如},这些参数只能由Delphi或C++Builder使用与DLL相同的共享内存管理器,甚至不能用于这些函数的所有版本。在
string
和{因此您将无法直接使用DLL,不使用C也不使用ctypes。
String
不映射到c_char_p
,不同的类型ShortString
等等。唯一匹配的类型是c_bool
,但这不会让你走得太远。在您可以与DLL的作者交谈,告诉他们阅读我的文章,介绍如何编写可以被其他语言使用的DLL:DLLs dos and don'ts。在
或者你可以找到一个使用Delphi或C++Bulder为DLL编写包装器的人,它包装函数并将Delphi特定类型转换为与C兼容的类型,比如}(
char *
(PAnsiChar
)或{PWideChar
)。在我无法阅读您链接的页面,因此我不知道您是否有权访问源代码。如果是这样的话,你可以试着找到一个修改导出的人,这样它们就可以直接从C中使用了。在
FWIW,这些类型也可以在FreePascal中找到,但是在那里你会遇到同样的问题。解决办法也是一样的。
相关问题 更多 >
编程相关推荐