Python Type Exception: Read Access Violation

I am trying to connect to a PLC via a DLL (C API distributed by the PLC manufacturer). I am using Python 3.1, which is built into the scripting environment in other software (x64 - Windows 7).

I managed to get some DLL functions, but now get a "Read Access Violation" which I cannot solve.

DLL function information:

LONG AdsSyncReadReq( PAmsAddr pAddr, ULONG nIndexGroup, ULONG nIndexOffset, ULONG nLength, PVOID pData ); 

Options:

  • pAddr: [in] NetId structure and ADS server port number.
  • nIndexGroup: [in] Index group.
  • nIndexOffset: [in] The offset of the index.
  • nLength: [in] Data length in bytes.
  • pData: [out] Pointer to a data buffer that will receive data.
  • Return value: returns the error status of the function.

AmsAddr Structure:

 typedef struct { AmsNetId netId; USHORT port; } AmsAddr, *PAmsAddr; 

AmsNetId Structure

 typedef struct { UCHAR b[6]; } AmsNetId, *PAmsNetId; 

Python implementation:

 # -*- coding: utf-8 -*- from ctypes import * #I've tried OleDll and windll as wel.. ADS_DLL = CDLL("C:/Program Files/TwinCAT/Ads Api/TcAdsDll/x64/TcAdsDll.dll") class AmsNetId(Structure): _fields_ = [('NetId', c_ubyte*6)] class AmsAddr(Structure): _fields_=[('AmsNetId',AmsNetId),('port',c_ushort)] # DLL function working fine version = ADS_DLL.AdsGetDllVersion() print(version) #DLL function working fine errCode = ADS_DLL.AdsPortOpen() print(errCode) #DLL function using the AmsAddr() class, working fine amsAddress = AmsAddr() pointer_amsAddress = pointer(amsAddress) errCode = ADS_DLL.AdsGetLocalAddress(pointer_amsAddress) print(errCode) contents_amsAddres = pointer_amsAddress.contents #Function that doens't work: errCode = ADS_DLL.AdsSyncReadReq() print(errCode) # --> errCode = timeout error, normal because I didn't pass any arguments # Now with arguments: plcNetId = AmsNetId((c_ubyte*6)(5,18,18,27,1,1)) #correct adress to the PLC plcAddress = AmsAddr(plcNetId,801) #correct port to the PLC nIndexGroup = c_ulong(0xF020) nIndexOffset = c_ulong(0x0) nLength = c_ulong(0x4) data = c_void_p() pointer_data = pointer(data) #I tried with an without the following 2 lines, doesn't matters ADS_DLL.AdsSyncReadReq.argtypes=[AmsAddr,c_ulong,c_ulong,c_ulong,POINTER(c_void_p)] ADS_DLL.AdsSyncReadReq.restype=None #This line crashes errCode = ADS_DLL.AdsSyncReadReq(plcAddress,nIndexGroup,nIndexOffset,nLength,pointer_data) print(errCode) >>>> Error in line 57: exception: access violation reading 0xFFFFFFFFFFFFFFFF 

I hope someone cannot understand what happened. I am only an advanced beginner in Python programming with no experience at all in C

Thank you in advance

+4
source share
1 answer

You are passing an invalid pointer, instead specify a valid memory buffer:

 data = create_string_buffer(nLength) 

The argument should be just c_void_p instead of POINTER(c_void_p) if PVOID means void * . Do not set restype to None (function returns LONG ).

Also go pointer(plcAddress) (specify POINTER(AmsAddr) in argtypes types).

Use the correct calling convention (choose between cdll, windll, oledll).

+2
source

All Articles