固定结构以避免 AccessViolationException [英] Pinning a Structure to avoid AccessViolationException

查看:35
本文介绍了固定结构以避免 AccessViolationException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am calling an function from a DLL which is loaded run-time (Using LoadLibrary()). This DLL is written in C++ and my code is in C#. API requires Structure Pointer. I am passing "ref" instead of Pointer.

在执行此操作时,我收到AccessViolationException".经过 3 天的谷歌搜索,我认为问题可以通过固定结构来解决,这样 GC 就不会打扰它.(参见:通过引用传递结构导致 AccessViolationException)

While doing this, I getting "AccessViolationException". After 3 days of Googling, I think the problem could be solved by Pinning the Structure so that GC won't disturb it. (See: Passing struct by reference causing AccessViolationException)

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

My question is Can I pin a structure without using any Pointers? Because I don't want to pass a pointer to function.

代码如下:

    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 甚至 Passed IntPtr.Zero 仍然出现错误 */

/* Call to fp_ReadMessage gives me "AccessViolationException". I have tried making that Ref to IntPtr even Passed IntPtr.Zero Still I am getting the error */

}
    }
}

问候,斯旺南!

推荐答案

我不认为固定在这里对您有帮助.CLR 将确保您传递给互操作调用的任何参数在调用返回之前不会在内存中移动.

I don't think pinning will help you here. The CLR will ensure that any parameters you pass to an interop call don't move in memory until the call returns.

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

So the only situation when you need to do some manual pinning is if the function you call stores the pointer and writes to it later.

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

To know why you get an access violation, we need more information about the native function you're calling (like the function signature).

这篇关于固定结构以避免 AccessViolationException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆