I'm developing an application which communicates with a Siemens S7 PLC via OPC.
The main application needs to be compiled for x64 architecture in .NET 4.0 and is
written in C# (VS 2010).
For the communication to the OPC server i'm using the OpcRcwDa.dll which is included
with the Simatic NET package of Siemens.
I used the example code from the Simatic SDK (asyncnet) and when i build this one with for x86 architecture everything works fine, but when i build it, with x64 architecture, i get the same Exception as in my application: "AccessViolationException, attempted to read or write protected memory".
I'm really desperate and it would be nice when someone could help me. Down here i put a code snippet of the adding of some items to the OPC-connection, the function in which the exception occures.
public bool StartOPCConnection()
{
bool retval = false;
Type svrComponenttyp;
IntPtr pResults = IntPtr.Zero;
IntPtr pErrors = IntPtr.Zero;
int bActive = 1;
int dwRequestedUpdateRate = 250;
int hClientGroup = 0;
int dwLCID = iLOCALE_ID;
int pRevUpdateRate;
int TimeBias = 0;
float deadband = 0;
GCHandle hTimeBias, hDeadband;
hTimeBias = GCHandle.Alloc(TimeBias, GCHandleType.Pinned);
hDeadband = GCHandle.Alloc(deadband, GCHandleType.Pinned);
Guid iidRequiredInterface = typeof(IOPCItemMgt).GUID;
svrComponenttyp = System.Type.GetTypeFromProgID(this.sLOCAL_SERVER);
try
{
pIOPCServer = (IOPCServer)System.Activator.CreateInstance(svrComponenttyp);
try
{
OPCITEMDEF[] ItemDefArray;
pIOPCServer.AddGroup(sGROUP_NAME,
bActive,
dwRequestedUpdateRate,
hClientGroup,
hTimeBias.AddrOfPinnedObject(),
hDeadband.AddrOfPinnedObject(),
dwLCID,
out nSvrGroupID,
out pRevUpdateRate,
ref iidRequiredInterface,
out pobjGroup1);
InitReqIOInterfaces();
ItemDefArray = new OPCITEMDEF[uiAMOUNT_OF_ITEMS];
for (int iArrayIndex = 0; iArrayIndex < uiAMOUNT_OF_ITEMS; iArrayIndex++)
{
ItemDefArray[iArrayIndex].szAccessPath = "";
ItemDefArray[iArrayIndex].szItemID = saItemNames[iArrayIndex];
ItemDefArray[iArrayIndex].bActive = 1;
ItemDefArray[iArrayIndex].hClient = iArrayIndex;
ItemDefArray[iArrayIndex].dwBlobSize = 0;
ItemDefArray[iArrayIndex].pBlob = IntPtr.Zero;
ItemDefArray[iArrayIndex].vtRequestedDataType = 6;
}
try
{
OPCITEMDEF[] tempItemDefArray = new OPCITEMDEF[uiAMOUNT_OF_ITEMS];
for (int idx = 0; idx < uiAMOUNT_OF_ITEMS; idx++)
{
tempItemDefArray[idx] = ItemDefArray[idx];
}
lock ((IOPCItemMgt)pobjGroup1)
{
((IOPCItemMgt)pobjGroup1).AddItems(uiAMOUNT_OF_ITEMS, tempItemDefArray, out pResults, out pErrors);
}
ItemSvrHandleArray = new int[uiAMOUNT_OF_ITEMS];
int[] errors = new int[uiAMOUNT_OF_ITEMS];
IntPtr pos = pResults;
Marshal.Copy(pErrors, errors, 0, uiAMOUNT_OF_ITEMS);
for (int idx = 0; idx < uiAMOUNT_OF_ITEMS; idx++)
{
if (errors[idx] == 0)
{
OPCITEMRESULT[] result = new OPCITEMRESULT[uiAMOUNT_OF_ITEMS];
result[idx] = new OPCITEMRESULT();
result[idx] = (OPCITEMRESULT)Marshal.PtrToStructure(pos, typeof(OPCITEMRESULT));
pos += Marshal.SizeOf(typeof(OPCITEMRESULT));
ItemSvrHandleArray[idx] = result[idx].hServer;
retval = true;
}
else
{
pIOPCServer.GetErrorString(errors[idx], iLOCALE_ID, out sErrors[idx]);
retval = false;
}
}
Marshal.DestroyStructure(pos, typeof(OPCITEMRESULT));
}
catch (AccessViolationException error)
{
lc.AddLog(LoggingState.EXCEPTION, error.ToString());
retval = false;
}
}
catch (System.Exception error)
{
lc.AddLog(LoggingState.EXCEPTION, error.ToString());
retval = false;
}
finally
{
if (hDeadband.IsAllocated) hDeadband.Free();
if (hTimeBias.IsAllocated) hTimeBias.Free();
}
}
catch (System.Exception error)
{
lc.AddLog(LoggingState.EXCEPTION, error.ToString());
retval = false;
}
return retval;
}