How to prevent violation of access to unmanaged DLL call?

We have inherited a legacy system for reading on and from meter cannons. This system was originally based on XP with .Net 1.1 (VS2003?). By recompiling it on VS2008 with .net 3.5, we get an access violation when dll is called (we don’t touch dll). The source program (using basically the same code) works fine on our production machine.

Crash:

[System.AccessViolationException]
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

code:

[DllImport("tinydb.dll",CallingConvention=CallingConvention.Cdecl)]
static extern Int16 db_fillnew(Int16 recno,IntPtr buffer,Int16 dbn);
     :
     :
    IntPtr buffer = Marshal.AllocHGlobal(1024); 
     :
     :
foreach (Round round in roundList)
{
    RoundRec roundRec=new RoundRec();
    roundRec.Book=Int16.Parse(round.Reference);
    roundRec.NLegend=round.Name;
    Marshal.StructureToPtr(roundRec,buffer,true);
    status = db_fillnew(ROUND_REC,buffer,0); // <=CRASHES HERE

It always flies a second time around the loop.

Here is the structure of the entry:

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
struct RoundRec
{
    public Int16 Book;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 9)]
    public string NLegend; public string LastReadRefNo;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 9)]
    public string LastNoAccessRefNo;
}
+3
source share
1 answer

Try to allocate and free memory for each record:

foreach (Round round in roundList)
{
  RoundRec roundRec = new RoundRec();
  roundRec.Book=Int16.Parse(round.Reference);
  roundRec.NLegend = round.Name;

  IntPtr buffer = Marshal.AllocHGlobal(Marshal.SizeOf(roundRec));

  Marshal.StructureToPtr(roundRec, buffer, true);
  status = db_fillnew(ROUND_REC, buffer, 0);

  Marshal.FreeHGlobal(buffer);
}
+2
source

Source: https://habr.com/ru/post/1719004/


All Articles