Python可以调用DLL中的Delphi函数吗?

10

我正在尝试调用一个似乎是由Delphi创建的DLL中的函数。该DLL支持的一些示例功能包括:

function oziDeleteWpByName(var name:pansichar):integer;stdcall

我编写的Python代码无法访问上述函数。

from ctypes import *
libc = cdll.OziAPI
name ='test'

pi = pointer(name)

delname = libc.oziDeleteWpByName

delname(name)

看起来我正在向函数传递错误的数据类型。有任何关于如何正确执行的想法吗?

谢谢,它奏效了。现在请帮忙处理这个函数:

function oziGetOziVersion(var Version:pansichar;var DataLength:integer):integer;stdcall; OziExplorer的版本将返回到Version变量中。

现在当我需要返回'var version'时该如何传递呢?


“var name:pansichar” 意味着 “name” 参数可以被修改并返回给调用者。函数真的这样做了吗?您计划在函数返回后读取“name”的内容吗? - David Heffernan
另外,你使用的是哪个版本的Python?这可能会影响字符串编码。 - David Heffernan
是的,那个“var”声明有些可疑。如果你,用户1138...编写了那个DLL,为什么要这样做呢? - Warren P
2个回答

13
from ctypes import *

# Not strictly needed but it's good to be explicit.
windll.OziAPI.oziDeleteWpByName.argtypes = [POINTER(c_char_p)]
windll.OziAPI.oziDeleteWpByName.restype = c_int

p = c_char_p('test')
retval = windll.OziAPI.oziDeleteWpByName(byref(p))

已更新 argtypesrestype - yak
我的Python无法找到windll.OziAPI - http://stackoverflow.com/questions/27910191/windll-oziapi-windowserror-module-not-found - ABM

1
在Delphi中,var参数是按引用传递的。所以你传递的是一个指向PAnsiChar(也称为C风格字符串指针)的指针。如果你传递的是一个字符串指针,而不是一个指向字符串指针的指针,那么它将不起作用。

我在那段Python代码中也没有看到任何指定stdcall调用约定的内容。Python中的cdll默认使用cdecl吗?如果是这样,这也会导致问题! - LaKraven
我非常确定,通过dll调用并由Python运行时库加载和调用的任何内容,都将始终使用Windows标准调用约定。 - Warren P
2
@Warren 不,LaKraven是对的。 cdllwindll是指定调用约定的方式。此外,在x86上至少没有Windows标准的调用约定。一些库使用stdcall,而另一些则使用cdecl。例如,考虑msvcrt。它全部都是cdecl - David Heffernan
哦,对了。我的错。我太偏向Delphi了,以至于认为stdcall是Windows标准,但实际上并不是。这在“Visual Basic和Delphi的人”中很常见。 - Warren P
1
@DavidHeffernan 这是今天你和我第一次达成共识 :) - LaKraven

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接