C# AccessViolationException如果我将变量声明为公共成员而不是局部变量

C# AccessViolationException如果我将变量声明为公共成员而不是局部变量,c#,C#,我有两个互操作数据结构作为类中的私有成员 public class RunInterop { private AlphaShapeCg _alphaHandler; private DoubleCgList alphaLevels; private FaceCgList faceCgList; public RunInterop() { faceCgList =new FaceCgList();

我有两个互操作数据结构作为类中的私有成员

public class RunInterop
{

        private AlphaShapeCg _alphaHandler;
        private DoubleCgList alphaLevels;
        private FaceCgList faceCgList;
    public RunInterop()
        {
            faceCgList =new FaceCgList();
            alphaLevels = new DoubleCgList();
            Interop_Init(ref _alphaHandler, ref faceCgList, ref alphaLevels);

           Interop_Run(ref _alphaHandler);
        }
}
现在的问题是,我将在
Interop\u Run
行获得一个
System.AccessViolationException

但是,如果我按照以下方式重写代码:

public class RunInterop
{
   private AlphaShapeCg _alphaHandler;
    public RunInterop()
        {
           var faceCgList =new FaceCgList();
           var alphaLevels = new DoubleCgList();
            Interop_Init(ref _alphaHandler, ref faceCgList, ref alphaLevels);

           Interop_Run(ref _alphaHandler);
        }
}
那我就不会有任何问题了。你知道为什么会这样吗


Edit:真正令人困惑的是,如果我将
faceCgList
alphaLevels
都声明为局部变量,那么问题就会消失?
Interop\u InitInterop\u Run中会发生什么?您正在将两个成员alphaLevelsfaceCgList传递到Interop_Init-可能是在调用Interop_Run时保留了一些对它们的引用,在这一点上,它似乎正在访问另一个类的私有成员

编辑:只是一个想法:)

编辑:我发现这篇文章解释了Mono中托管/非托管封送的工作原理-我正在努力为Microsoft的dotNET框架找到一篇类似的信息性文章,但我猜想它应该以类似的方式工作。以下是文章中的一句话:

此外,如果(a)结构位于堆栈上,以及(b) 该结构仅包含可blittable类型,如果传递 通过引用将结构转换为非托管函数,该结构将 直接传递给非托管函数,无需中间 非托管内存拷贝


互操作初始化互操作运行中会发生什么?您正在将两个成员alphaLevelsfaceCgList传递到Interop_Init-可能是在调用Interop_Run时保留了一些对它们的引用,在这一点上,它似乎正在访问另一个类的私有成员

编辑:只是一个想法:)

编辑:我发现这篇文章解释了Mono中托管/非托管封送的工作原理-我正在努力为Microsoft的dotNET框架找到一篇类似的信息性文章,但我猜想它应该以类似的方式工作。以下是文章中的一句话:

此外,如果(a)结构位于堆栈上,以及(b) 该结构仅包含可blittable类型,如果传递 通过引用将结构转换为非托管函数,该结构将 直接传递给非托管函数,无需中间 非托管内存拷贝



\u alphaHandler
在哪里声明?@DanielA.White,问题已更新\u alphaHandler初始化在哪里?@Graviton-这是有意设置的格式吗?@Graviton-您是否启用了混合模式调试,并为您正在使用的任何东西(DirectX)启用了调试符号?我想知道这段代码的互操作端是否会给出一个调用堆栈?声明了
\u alphaHandler
在哪里?@DanielA.White,问题更新了\u alphaHandler初始化在哪里?@Graviton-这是有意的格式设置吗?@Graviton-您是否启用了混合模式调试,并为您正在使用的任何东西(DirectX?)启用了调试符号?我想知道这段代码的互操作端是否会给出一个调用堆栈?我不这么认为,原因是如果我将faceCgList和AlphaLevel都声明为局部变量,问题就会迎刃而解?当您将它们声明为私有成员时,当您进入非托管代码时,dotNET会试图保护内存空间。对于局部变量,情况可能并非如此。这取决于您何时希望作为成员而不是局部变量访问这些结构。我添加了一个想法,即在Interup_运行后将私有成员分配给局部变量,但如果在调用RunInterop之前需要在其他地方设置它们,则可以在调用Interop_Init之前将局部变量设置为其成员对应项的副本。感谢VeldUI,至于在调用Interop_Run时,它可能会保留一些对它们的引用,在这一点上它可能会访问另一个类的私有成员,我可以知道这是怎么发生的吗?似乎不可能。我最初的措辞可能不正确。在c#中,每个结构[S](alphaLevels/faceCgList)都存在于其分配的内存空间[M]中,并且由于成员声明为私有,dotNET只允许类RunInterop访问[M]。[S] 通过引用传递给Interop_Init,这意味着非托管代码也将引用[M]。调用Interop_Run时可以再次访问此内存引用,但由于它不是通过某个参数传入的,dotNET会将其视为对[M]的无效引用。我不这么认为,原因是如果我将faceCgList和AlphaLevel都声明为局部变量,当你将它们声明为私有成员时,当你进入非托管代码时,dotNET会试图保护内存空间。对于局部变量,情况可能并非如此。这取决于您何时希望作为成员而不是局部变量访问这些结构。我添加了一个想法,即在Interup_运行后将私有成员分配给局部变量,但如果在调用RunInterop之前需要在其他地方设置它们,则可以在调用Interop_Init之前将局部变量设置为其成员对应项的副本。感谢VeldUI,至于在调用Interop_Run时,它可能会保留一些对它们的引用,在这一点上它可能会访问另一个类的私有成员,我可以知道这是怎么发生的吗?似乎不可能。我最初的措辞可能不正确。在c#中,每个结构[S](alphaLevels/faceCgList)都存在于其分配的内存空间[M]中,因为该成员被声明为priv
public class RunInterop
{
    private AlphaShapeCg _alphaHandler;
    private DoubleCgList _alphaLevels;
    private FaceCgList _faceCgList;

    public RunInterop()
    {
        AlphaShapeCg faceCgList = new FaceCgList();
        DoubleCgList alphaLevels = new DoubleCgList();
        Interop_Init(ref _alphaHandler, ref faceCgList, ref alphaLevels);
        Interop_Run(ref _alphaHandler);
        _alphaLevels = alphaLevels;
        _faceCgList = faceCgList;
    }
}