2016-04-21 36 views
0

调用DLL我有一个.dll名为my.dll,有4个功能,堪称蟒蛇3.5使用:
myDLL = ctypes.cdll.LoadLibrary(Path:\to\my.dll)在Python 3 LPSTR

我的问题是调用一些存在LPSTR功能:

#include "stdafx.h" 
#include "newheader.h"  
double _stdcall pain_function(double arg1, double arg2, LPSTR arg_string_with_spaces) 

其他3个电话my.dll工作正常。

下面是我试过的pain_function代码:

import ctypes 
from ctypes import wintypes 

# Load dll 
myDLL = ctypes.WinDLL(Path:\to\my.dll) 

# Call function 
pain_function = myDLL.pain_function 

# Typecast the arguments 
pain_function.argtypes = [ctypes.c_double, ctypes.c_double, wintypes.LPSTR] 

# Typecast the return 
pain_function.restype = ctypes.c_double 


pain_return = pain_function(arg1, arg2, some_string) 

pain_return返回一些荒谬的数字。我尝试了一些变化,主要是线沿线的:我在这里看着其他地方

some_string = ctypes.create_string_buffer(b' ' * 200) 

  1. python-ctypes-prototype-with-lpcstr-out-parameter

  2. Using String Parameters in DLL Function Calls

这是什么正确的方式将200个空格的字符串传递给dll?

预先感谢您

+0

'LPSTR'是一个'c_char_p'的lias。如果你愿意,你可以使用'from ctypes import wintypes; wintypes.LPSTR'。既然它不是'LPCSTR'(一个常量字符串),我们应该假设函数修改缓冲区,所以你使用'create_string_buffer'是正确的。没有必要对这个值进行编码。只需使用“字节”字面值,例如'e = create_string_buffer(b''* 200)'。如果您对该值进行编码,请使用“mbcs”编码,而不是硬编码代码页1252. – eryksun

+0

至于无意义的编号,您没有显示完整的原型。如果'pain_function'具有'void'返回值,则设置'pain_function.restype = None'。如果它有一个'double'返回值,则设置'pain_function.restype = c_double'。等等。 – eryksun

+0

@eryksun谢谢! ...我认为有两个问题与代码(1)'restype',我固定(2)这个'LPSTR',所以现在我的argtype看起来像这样:'pain_function = ['ctypes.c_double,ctypes.c_double,wintypes .LPSTR]'但是 - 现在它只是返回一个double,还缺少了什么? –

回答

1

您指定的原型是:

double _stdcall pain_function(double arg1, double arg2, LPSTR arg_string_with_spaces) 

但使用:

myDLL = ctypes.cdll.LoadLibrary(Path:\to\my.dll) 

应该是,__stdcall调用约定:

myDLL = ctypes.WinDLL('Path:\to\my.dll') 
+0

可能Itay使用的是64位的Python,它没有什么区别。但使用'WinDLL'来支持32位Python更好。 – eryksun

+0

这是正确的我正在使用64位的Python。有趣的是,当我试图找出问题时,我尝试了两种方法,但没有什么区别。这就是说 - 我正在纳入这些建议。 –

+0

@ItayLivni,它在32位Python中很重要。在x86'stdcall'(即'WinDLL')中,被调用者在返回时会清除堆栈,这就是为什么你没有看到这个约定与C variadic函数(比如'printf')一起使用。如果'stdcall'函数被错误地称为'cdecl'(即'CDLL'),ctypes会检查这一点。在这种情况下,应引发异常,例如“ValueError:调用的参数数量不足(缺少N个字节)或错误的调用约定”,其中N是被调用者从堆栈清除的字节数。 – eryksun