Access Violation using Python Ctypes

1

I am trying to import and use a function from a DLL using Pythons ctypes module, but I keep getting this error:

Windows Error: exception: access violation writing 0x0000002C

I've had a look at the other questions on similar topics on here, but none seem to be able to provide an answer that works. My current code is as follows:

from ctypes import *

dll = "./WinlicenseSDK/WinlicenseSDK.dll"

mydll = cdll.LoadLibrary(dll)

name = c_char_p("A.N. Body")
org = c_char_p("ACME")
pcID = c_char_p("APC44567")
zero = c_int(0)
licenseKey = create_string_buffer("")    

mydll.WLGenLicenseFileKey(HASH, name, org, pcID, zero, zero, zero, zero, zero, licenseKey)

Context: I'm investigating licensing techniques for a piece of software. The above function generates a license key from hashing the parameters.

The last parameter for the WLGenLicenseFileKey is a string buffer that the generated key is written to.

I tried setting the argtypes for the function with mydll.WLGenLicenseFileKey.argtypes = ... but this won't work as there is not a string buffer ctypes raw type as there is for strings, ints, floats etc.

Can anybody tell me where I am going wrong?

EDIT:

The C/C++ function definition:

int WLGenLicenseFileKeyW(    
wchar_t* pLicenseHash,     
wchar_t* pUserName,     
wchar_t* pOrganization,    
wchar_t* pCustomData,     
wchar_t* pMachineID,   
int NumDays,    
int NumExec,    
SYSTEMTIME* pExpirationDate,     
int CountryId,     
int Runtime,     
int GlobalTime,    
char* pBufferOut    
);

That is all the information that the documentation gives on the function.

python
ctypes
asked on Stack Overflow Jul 18, 2012 by BigStuuu • edited Jul 20, 2012 by Mark Tolonen

1 Answer

3

The length of your licenseKey buffer is one byte, and you are not passing Unicode strings. I'm not in front of my PC, but I this should be close assuming your parameters are otherwise correct. Make sure to call the W version of the function. You also don't need to create the exact types as long as they are ints and pointers.

buffer = create_string_buffer(REQUIRED_BUFSIZE)
mydll.WLGenLicenseKeyW(u"A.N. Body", u"ACME", u"APC44567", None, None, 0, 0, None, 0, 0, 0, buffer)

If you do want to use argtypes, then this is what you want:

mydll.WLGenLicenseKeyW.argtypes = [c_wchar_t,c_wchar_t,c_wchar_t,c_wchar_t,c_wchar_t,c_int,c_int,c_void_p,c_int,c_int,c_int,c_char_p]

SYSTEMTIME would also need to be defined if you want to pass something besides NULL.

edit

I found some documentation. The function uses the stdcall calling convention, so use:

mydll = WinDLL(dll)
answered on Stack Overflow Jul 20, 2012 by Mark Tolonen • edited Jul 20, 2012 by Mark Tolonen

User contributions licensed under CC BY-SA 3.0