从C#调用DLL时发生内存访问违规异常错误

Memory AccessViolationException Error Calling DLL From C#

本文关键字:访问 异常 错误 内存 调用 DLL      更新时间:2023-10-16

在从C#调用已编译的DLL时,遇到了一个奇怪的内存读/写错误。我使用DllImport来获得我们需要的函数的句柄,该函数向指向int(即int*out)的参数指针写入返回值。该函数在一个线程内被多次调用,并在第一个线程的执行寿命内成功运行。但是,如果在第一个线程完成后启动另一个线程,则对外部dll的调用会引发AccessViolationException。由于来自第一个线程的多个调用成功执行,我认为这在某种程度上与第一个线程没有释放指向相关整数参数(?)的指针有关。如果是,我如何明确地释放内存?或者,也许有人对这里可能发生的事情有不同的见解?非常感谢。

编辑:丹尼要求更多细节,我很乐意接受。以下是调用外部例程的位置:

    int success = -1;
    unsafe
    {
        int res = 0;
        int* res_ptr = &res;
        int len = cmd.ToCharArray().Length;
        int* len_ptr = &len;
        CmdInterpreter(ref cmd, len_ptr, res_ptr);
        success = *res_ptr;
    }

其中CmdEnterprise定义为:

    [DllImport("brugs.dll", EntryPoint="CmdInterpreter", 
        ExactSpelling=false, CallingConvention = CallingConvention.StdCall)]
    public static unsafe extern void CmdInterpreter(ref string cmd, int *len, int *res);

请告诉我,如果有任何额外的信息会有帮助。非常感谢。

考虑到只有当涉及多个线程时才会出现问题,可能是命令解释器DLL使用了某种线程本地存储,并且操作不正确。它还可能与第二个线程(生成错误的线程)的COM初始化状态有关。

如果您启动新线程并在对第一个/main线程的DLL进行任何调用之前将其调用到DLL,那么了解会发生什么将是很有趣的。如果它有效,那可能支持线程本地存储理论。如果失败,这将支持COM状态理论。

它可能是[DllImport]。如果您发布[DllImport]签名和DLL的ptotype,也许我们可以发现问题。

我读到托管、本机和COM互操作团队在CodePlex上发布了PInvoke互操作助手。http://www.codeplex.com/clrinterop/Release/ProjectReleases.aspx?ReleaseId=14120