I try to communicate with a PLC through a DLL (C API interface distributed by the manufacturer of the PLC). I'm using Python 3.1 who is embedded as a scripting environment in a other software (x64 - Windows 7).
I managed to get a few DLL functions working, but now a get an "Access violation reading" that I can't solve.
Information about the DLL function:
LONG AdsSyncReadReq(
PAmsAddr pAddr,
ULONG nIndexGroup,
ULONG nIndexOffset,
ULONG nLength,
PVOID pData
);
Parameters:
Structure AmsAddr:
typedef struct {
AmsNetId netId;
USHORT port;
} AmsAddr, *PAmsAddr;
Structure AmsNetId
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 anyone can't figure out what's wrong. I'm only a advanced novice in Python programming with no experience at all in C
Thanks in advance
You're passing invalid pointer, provide a valid memory buffer instead:
data = create_string_buffer(nLength)
The argument should be just c_void_p
instead of POINTER(c_void_p)
if PVOID
means void *
. Don't set restype to None
(the function returns LONG
).
Also pass pointer(plcAddress)
(specify POINTER(AmsAddr)
in argtypes).
Use correct calling convention (choose between cdll, windll, oledll).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With