2016-04-21 39 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