5

DLL (PLC の製造元が配布する C API インターフェイス) を介して PLC と通信しようとしています。他のソフトウェア (x64 - Windows 7) にスクリプト環境として組み込まれている Python 3.1 を使用しています。

いくつかの DLL 関数を動作させることができましたが、解決できない「アクセス違反の読み取り」が発生しました。

DLL 関数に関する情報:

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

パラメーター:

  • pAddr: [in] ADS サーバーの NetId とポート番号を含む構造。
  • nIndexGroup: [in] インデックス グループ。
  • nIndexOffset: [in] インデックス オフセット。
  • nLength:[in] バイト単位のデータの長さ。
  • pData: [out] データを受け取るデータ バッファーへのポインター。
  • 戻り値: 関数のエラー ステータスを返します。

構造 AmsAddr:

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

構造体 AmsNetId

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

Python 実装:

# -*- 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

何が悪いのか誰にもわからないことを願っています。私は Python プログラミングの上級初心者であり、C の経験はまったくありません。

前もって感謝します

4

1 に答える 1

2

無効なポインタを渡しています。代わりに有効なメモリ バッファを指定してください。

data = create_string_buffer(nLength)

引数は、 if meansc_void_pの代わりにjust にする必要があります。restype を に設定しないでください(関数は を返します)。POINTER(c_void_p)PVOIDvoid *NoneLONG

また、渡すpointer(plcAddress)( POINTER(AmsAddr)argtypes で指定)。

正しい呼び出し規則を使用してください (cdll、windll、oledll から選択してください)。

于 2013-03-18T08:53:02.827 に答える