固定结构以避免AccessViolationException

时间:2010-10-18 10:06:41

标签: c# dll access-violation

我从一个运行时加载的DLL调用一个函数(使用LoadLibrary())。 这个DLL是用C ++编写的,我的代码是用C#编写的。 API需要结构指针。我正在传递“ref”而不是Pointer。

执行此操作时,我收到“AccessViolationException”。经过3天的谷歌搜索,我认为问题可以通过固定结构来解决,这样GC就不会打扰它。 (见:Passing struct by reference causing AccessViolationException

我的问题是我可以在不使用任何指针的情况下固定结构吗?因为我不想传递指向函数的指针。

代码如下:

    public class TestClass
    {
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi)]      
 public struct MsgFormat
{
  public Int32 MsgID;
public Int32 RxID;
[MarshalAs(UnmanagedType.ByValArray,SizeConst=13)]
public Char[] MsgData;
}

unsafe public delegate Int32 ReadMessage(Int32 ConnectID,ref MsgFormat Message);
ReadMessage fp_ReadMessage;


void Connection()
{
IntPtr pDLLHandle;

pDLLHandle=LoadLibrary(Connect.dll);  // Load Required DLL

IntPtr fPtr= GetProcAddress(pDLLHandle,"ReadMessage"); 
fp_ReadMessage=(ReadMessage)Marshal.GetDelegateForFunctionPointer(fPtr,typeof(ReadMessage)); // Get Function Pointer for API
}

void Read()
{
  MsgFormat Rx_Msg=new MsgFormat();
  Int32 nReturnValue;
  Int32 nConnectID=0;  // Value is assigned for Testing the Function
/* Also Tried:
  Rx_Msg.MsgData=new Char[13];  */ 
nReturnValue= fp_ReadMessage(nConnectID,ref Rx_Msg);  // "ReadMessage" will return info in Rx_Msg;

/ *调用fp_ReadMessage会给我“AccessViolationException”。我试过让Ref到IntPtr甚至通过IntPtr.Zero我仍然收到错误* /

}
    }
}

此致 Swanand!

1 个答案:

答案 0 :(得分:0)

我认为钉住会帮助你。 CLR将确保传递给interop调用的任何参数在调用返回之前不会在内存中移动。

因此,当您需要执行某些手动固定时,唯一的情况是您调用的函数是否存储指针并稍后写入指针。

要知道访问冲突的原因,我们需要有关您正在调用的本机函数的更多信息(如函数签名)。