从C#调用非托管C++库(dll)会产生访问冲突错误(0xc0000005)

本文关键字:访问冲突 0xc0000005 错误 dll C++ 调用 | 更新日期: 2023-09-27 18:00:25

很抱歉问了这么长的问题。我只是想把我目前所知道的关于这个问题的一切都包括在内。

我正在使用Visual Studio 2008在C#中创建一个Windows窗体程序,该程序调用用C++编写的库
C++DLL分析由几个样本组成的测量数据。样本通过函数(PDSetWaveSample)传递给库,该函数将结构作为参数
在设置完所有样本后,使用另一个函数(PDPreProcess)处理测量数据,该函数也将结构作为参数
C++DLL在其内部数据结构中保存所有测量数据,并进行所有处理以获得结果。

在程序开始处理测量数据之前,一切似乎都正常工作。此时,程序崩溃并退出,并出现以下错误:

程序"XXX.vshost.exe:Managed"已退出,代码为1073741819(0xc0000005)。

稍后我将在这个问题中添加更多的调试信息和C#源代码。

你有任何关于如何前进的提示吗?或者可能是什么原因导致的

我运行的是Windows XP Professional,版本2002 SP 3。

当程序崩溃时,它首先给出这个错误消息

类型为"System"的未处理异常。未知模块中出现ExecutionEngineException。

以及中断或继续的可能性。我选择分手。

之后,我看了看组装:

没有为任何调用堆栈帧加载任何符号。无法显示源代码。

根据调试器的说法,错误发生时的程序集如下所示:

7C90E4FA  call        7C90E528 
7C90E4FF  mov         eax,dword ptr [esp] 
7C90E502  mov         esp,ebp 
7C90E504  pop         ebp  
7C90E505  ret              
7C90E506  lea         esp,[esp] 
7C90E50D  lea         ecx,[ecx] 
7C90E510  mov         edx,esp 
7C90E512  sysenter         
==>7C90E514  ret              
7C90E515  lea         esp,[esp] 
7C90E51C  lea         esp,[esp] 
7C90E520  lea         edx,[esp+8] 
7C90E524  int         2Eh  
7C90E526  ret              
7C90E527  nop              
7C90E528  push        ebp  
7C90E529  mov         ebp,esp 
7C90E52B  pushfd           

执行在7C90E514 ret(我用===>标记)处停止

输出窗口显示以下消息:

'CalculationForm.exe': Loaded 'C:'CalculationForm'CalculationForm'bin'Debug'CalculationForm.exe', No native symbols in symbol file.  
'CalculationForm.exe': Loaded 'C:'WINNT'system32'ntdll.dll'  
'CalculationForm.exe': Loaded 'C:'WINNT'system32'kernel32.dll'  
'CalculationForm.exe': Loaded 'C:'WINNT'system32'sysfer.dll'  
'CalculationForm.exe': Loaded 'C:'WINNT'system32'mscoree.dll'  
'CalculationForm.exe': Loaded 'C:'WINNT'system32'advapi32.dll'  
'CalculationForm.exe': Loaded 'C:'WINNT'system32'rpcrt4.dll'  
'CalculationForm.exe': Loaded 'C:'WINNT'system32'secur32.dll'  
'CalculationForm.exe': Loaded 'C:'WINNT'system32'shlwapi.dll' 
'CalculationForm.exe': Loaded 'C:'WINNT'system32'gdi32.dll' 
'CalculationForm.exe': Loaded 'C:'WINNT'system32'user32.dll' 
'CalculationForm.exe': Loaded 'C:'WINNT'system32'msvcrt.dll' 
'CalculationForm.exe': Loaded 'C:'WINNT'system32'imm32.dll' 
'CalculationForm.exe': Loaded 'C:'WINNT'Microsoft.NET'Framework'v2.0.50727'mscorwks.dll' 
'CalculationForm.exe': Loaded 'C:'WINNT'WinSxS'x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.4053_x-ww_e6967989'msvcr80.dll' 
'CalculationForm.exe': Loaded 'C:'WINNT'system32'shell32.dll' 
'CalculationForm.exe': Loaded 'C:'WINNT'WinSxS'x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.6028_x-ww_61e65202'comctl32.dll' 
'CalculationForm.exe': Loaded 'C:'WINNT'system32'comctl32.dll'
'CalculationForm.exe': Loaded 'C:'WINNT'Microsoft.NET'Framework'v2.0.50727'Culture.dll' 
'CalculationForm.exe': Unloaded 'C:'WINNT'Microsoft.NET'Framework'v2.0.50727'Culture.dll' 
'CalculationForm.exe': Loaded 'C:'WINNT'assembly'NativeImages_v2.0.50727_32'mscorlib'17179b71d7680399c00ce88ddc310209'mscorlib.ni.dll' 
'CalculationForm.exe' (Managed): Loaded 'C:'WINNT'assembly'GAC_32'mscorlib'2.0.0.0__b77a5c561934e089'mscorlib.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 
'CalculationForm.exe': Loaded 'C:'WINNT'system32'ole32.dll' 
'CalculationForm.exe': Loaded 'C:'WINNT'system32'MSCTF.dll' 
'CalculationForm.exe' (Managed): Loaded 'C:'Tyohakemisto'WaveRoller'CalculationForm'CalculationForm'bin'Debug'CalculationForm.exe', Symbols loaded. 
'CalculationForm.exe': Loaded 'C:'WINNT'Microsoft.NET'Framework'v2.0.50727'mscorjit.dll' 
'CalculationForm.exe': Loaded 'C:'WINNT'assembly'NativeImages_v2.0.50727_32'System'2f867d97fb1a34e4d6985780631574bb'System.ni.dll' 
'CalculationForm.exe': Loaded 'C:'WINNT'assembly'NativeImages_v2.0.50727_32'System.Drawing'f78f03ba3b1b21e3b26369402c117d33'System.Drawing.ni.dll' 
'CalculationForm.exe': Loaded 'C:'WINNT'assembly'NativeImages_v2.0.50727_32'System.Windows.Forms'06b728c1e4ea291d4febee5ca33db4b4'System.Windows.Forms.ni.dll' 
'CalculationForm.exe' (Managed): Loaded 'C:'WINNT'assembly'GAC_MSIL'System.Windows.Forms'2.0.0.0__b77a5c561934e089'System.Windows.Forms.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 
'CalculationForm.exe' (Managed): Loaded 'C:'WINNT'assembly'GAC_MSIL'System'2.0.0.0__b77a5c561934e089'System.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 
'CalculationForm.exe' (Managed): Loaded 'C:'WINNT'assembly'GAC_MSIL'System.Drawing'2.0.0.0__b03f5f7f11d50a3a'System.Drawing.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 
'CalculationForm.exe': Loaded 'C:'WINNT'assembly'NativeImages_v2.0.50727_32'System.Configuration'b2f3e4c45a980474c2dd08166038d645'System.Configuration.ni.dll' 
'CalculationForm.exe' (Managed): Loaded 'C:'WINNT'assembly'GAC_MSIL'System.Configuration'2.0.0.0__b03f5f7f11d50a3a'System.Configuration.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 
'CalculationForm.exe': Loaded 'C:'WINNT'assembly'NativeImages_v2.0.50727_32'System.Xml'8ee82dfeff03ca87492149cdcbfc3f21'System.Xml.ni.dll' 
'CalculationForm.exe' (Managed): Loaded 'C:'WINNT'assembly'GAC_MSIL'System.Xml'2.0.0.0__b77a5c561934e089'System.Xml.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 
'CalculationForm.exe': Loaded 'ImageAtBase0x10000000'
'CalculationForm.exe': Unloaded 'ImageAtBase0x10000000' 
'CalculationForm.exe': Loaded 'C:'WINNT'assembly'GAC_MSIL'Microsoft.VisualStudio.Debugger.Runtime'9.0.0.0__b03f5f7f11d50a3a'Microsoft.VisualStudio.Debugger.Runtime.dll' 
'CalculationForm.exe' (Managed): Loaded 'C:'WINNT'assembly'GAC_MSIL'Microsoft.VisualStudio.Debugger.Runtime'9.0.0.0__b03f5f7f11d50a3a'Microsoft.VisualStudio.Debugger.Runtime.dll' 
'CalculationForm.exe': Loaded 'C:'Program Files'Microsoft Visual Studio 9.0'Common7'Packages'Debugger'x86'Microsoft.VisualStudio.Debugger.Runtime.Impl.dll' 
'CalculationForm.exe': Loaded 'C:'WINNT'WinSxS'x86_Microsoft.VC90.CRT_1fc8b3b9a1e18e3b_9.0.30729.4148_x-ww_d495ac4e'msvcr90.dll' 
'CalculationForm.exe': Loaded 'C:'WINNT'system32'uxtheme.dll' 
'CalculationForm.exe': Loaded 'C:'WINNT'system32'xpsp2res.dll', Binary was not built with debug information. 
'CalculationForm.exe' (Managed): Loaded 'C:'CalculationForm'CalculationForm'bin'Debug'AxInterop.PDCOMMXLib.dll' 
'CalculationForm.exe': Loaded 'C:'WINNT'WinSxS'x86_Microsoft.Windows.GdiPlus_6595b64144ccf1df_1.0.6002.22509_x-ww_c7dad023'GdiPlus.dll' 
'CalculationForm.exe': Loaded 'C:'WINNT'system32'version.dll' 
'CalculationForm.exe': Unloaded 'C:'WINNT'system32'version.dll' 
'CalculationForm.exe': Loaded 'C:'WINNT'system32'MSCTFIME.IME' 
'CalculationForm.exe': Loaded 'C:'WINNT'system32'oleaut32.dll' 
'CalculationForm.exe': Loaded 'C:'WINNT'Microsoft.NET'Framework'v2.0.50727'diasymreader.dll' 
'CalculationForm.exe': Loaded 'C:'WINNT'system32'clbcatq.dll' 
'CalculationForm.exe': Loaded 'C:'WINNT'system32'comres.dll' 
'CalculationForm.exe': Loaded 'C:'WINNT'system32'version.dll' 
'CalculationForm.exe': Loaded 'C:'WINNT'system32'msi.dll' 
'CalculationForm.exe': Loaded 'C:'Nortek'PdCommX'PdCommX.dll', Binary was not built with debug information. 
'CalculationForm.exe': Loaded 'C:'WINNT'system32'mfc100.dll' 
'CalculationForm.exe': Loaded 'C:'WINNT'system32'msvcr100.dll' 
'CalculationForm.exe': Loaded 'C:'WINNT'system32'msimg32.dll'
'CalculationForm.exe': Loaded 'C:'WINNT'system32'msvcp100.dll' 
'CalculationForm.exe': Loaded 'C:'WINNT'system32'sxs.dll' 
'CalculationForm.exe' (Managed): Loaded 'C:' CalculationForm'CalculationForm'bin'Debug'Interop.PDCOMMXLib.dll'
'CalculationForm.exe': Loaded 'C:'WINNT'assembly'NativeImages_v2.0.50727_32'Accessibility'775f9f0da40c277eb7d460084858a2ac'Accessibility.ni.dll'
'CalculationForm.exe' (Managed): Loaded 'C:'WINNT'assembly'GAC_MSIL'Accessibility'2.0.0.0__b03f5f7f11d50a3a'Accessibility.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
The thread 'Win32 Thread' (0x1f08) has exited with code 0 (0x0).
The thread 'Win32 Thread' (0x1cc4) has exited with code 0 (0x0).
The thread 'Win32 Thread' (0x1598) has exited with code 0 (0x0).
The thread 'Win32 Thread' (0xaa8) has exited with code 0 (0x0). 
The thread 'Win32 Thread' (0x1db8) has exited with code 0 (0x0).
The thread 'Win32 Thread' (0x1e74) has exited with code 0 (0x0).
The thread 'Win32 Thread' (0x1958) has exited with code 0 (0x0).
The program '[4656] CalculationForm.exe: Managed' has exited with code 0 (0x0).
The program '[4656] CalculationForm.exe: Native' has exited with code 0 (0x0).

程序结束时,调用堆栈为:

ntdll.dll!7c90e514()    
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll] 
ntdll.dll!7c90df5a()    
kernel32.dll!7c8025db()     
mscorwks.dll!79e8c639()     
mscorwks.dll!79e8c56f()     
mscorwks.dll!79f7466d()     
mscorwks.dll!7a105cf1()     
mscorwks.dll!7a105e37()     
mscorwks.dll!7a1061db()     
mscorwks.dll!7a09c314()     
mscorwks.dll!79f504da()     
mscorwks.dll!79ef4755()     
ntdll.dll!7c9032a8()    
ntdll.dll!7c90327a()    
ntdll.dll!7c92a8c3()    
ntdll.dll!7c90e48a()    
ntdll.dll!7c94b721()    
ntdll.dll!7c919f68()    
ntdll.dll!7c919f68()    
ntdll.dll!7c919f68()    
ntdll.dll!7c919f68()    
ntdll.dll!7c910385()    
ntdll.dll!7c917c51()    
ntdll.dll!7c917e8f()    
mscorwks.dll!79e71b4c()     
mscorwks.dll!79e821f9()     
mscorwks.dll!79e96571()     
mscorwks.dll!79e965a4()     
mscorwks.dll!79e965c2()     
mscorwks.dll!79ecca87()     
mscorwks.dll!79ef531b()     
mscorwks.dll!79ef6dd8()     
mscorwks.dll!79ef6e76()     
mscorwks.dll!79ef4755()     
ntdll.dll!7c9032a8()    
ntdll.dll!7c90327a()    
ntdll.dll!7c92a8c3()    
ntdll.dll!7c90e48a()    
ntdll.dll!7c917ca7()    
ntdll.dll!7c917e8f()    
mscorwks.dll!7a0ecb29()     
mscorwks.dll!79f6879a()     
mscorwks.dll!79f68780()     
mscorwks.dll!79f73f3d()     
mscorwks.dll!79ecd659()     
mscorwks.dll!79e71b4c()     
mscorwks.dll!79e821f9()     
mscorwks.dll!79e96571()     
mscorwks.dll!79e965a4()     
mscorwks.dll!79e965c2()     
mscorwks.dll!79f87ad3()     
mscorwks.dll!79f87c32()     
mscorlib.ni.dll!792d5428()  
mscorlib.ni.dll!792d51d6()  
mscorlib.ni.dll!792d50be()  
mscorwks.dll!79e71b4c()     
mscorwks.dll!79e821f9()     
mscorwks.dll!79e96571()     
mscorwks.dll!79e965a4()     
mscorwks.dll!79f29e09()     
mscorwks.dll!79f2a1e0()     
mscorwks.dll!79f2a130()     
mscorwks.dll!79f29837()     
mscorwks.dll!79f298bc()     
mscorwks.dll!79f29967()     
System.ni.dll!7a574b73()    
System.Windows.Forms.ni.dll!7b1c87be()  
mscorwks.dll!79e71b4c()     
mscorwks.dll!79e821f9()     
System.Windows.Forms.ni.dll!7b1c86a0()  
System.Windows.Forms.ni.dll!7b1c8621()  
System.Windows.Forms.ni.dll!7b6fa167()  
mscorwks.dll!79e71b4c()     
mscorwks.dll!79e821f9()     
mscorwks.dll!79fc1fe2()     
mscorwks.dll!79fc219a()     
mscorwks.dll!79fc22be()     
mscorwks.dll!79f077ad()     
mscorwks.dll!79e8c4ec()     
mscorwks.dll!79e8840b()     
mscorwks.dll!79f13cb5()     
mscorwks.dll!79f1129c()     
mscorwks.dll!79f07e17()     
mscoree.dll!7900b77b()  
mscoree.dll!7900b73d()  
mscoree.dll!79004de3()  
kernel32.dll!7c817077()     

我已经为C++DLL创建了一个包装类。包装器类基于库的头文件:

#ifndef _PDWAVEAPI_H__  
#define _PDWAVEAPI_H__
#ifdef PDWAVE_EXPORTS
#define PDWAVE_API __declspec(dllexport)
#else
#define PDWAVE_API __declspec(dllimport)
#endif
typedef struct {
   bool  bValid;
   float fPressure;
   float fDistance;
   float fVel[4];
   unsigned short nAmp[4];
 } PDWaveSample;
typedef struct {
    float fST[4096];
    float fWinFloor;
    float fWinCeil;
    bool bUseWindow;
    bool bSTOk;
    bool bGetRawAST;
    bool bValidBurst;
 } PDWaveBurst;

PDWAVE_API int __stdcall PDSetWaveSample(PDWaveSample *pWaveSample);
PDWAVE_API int __stdcall PDPreProcess(int nSample, PDWaveBurst *pWaveBurst);

C#包装器类是:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices; // DllImport
namespace Cpp_LibraryApi
{
    [StructLayout(LayoutKind.Sequential)]
    public struct PDWaveSample
    {
        public bool bValid;                             
        public float fPressure;                         
        public float fDistance;                         
        public float[] fVel;
        public ushort[] nAmp
        // Constructor to initialize tables
        public static PDWaveSample Create()
        {
            PDWaveSample DataStruct = new PDWaveSample();
            DataStruct.fVel = new float[4];
            DataStruct.nAmp = new ushort[4];
            return DataStruct;
        }
    }
    [StructLayout(LayoutKind.Sequential)]
    public  struct PDWaveBurst {
        public float[] fST;
        public float fWinFloor;
        public float fWinCeil;
        public bool bUseWindow;
        public bool bSTOk;
        public bool bGetRawAST;
        public bool bValidBurst;
        public static PDWaveBurst Create()
        {
            PDWaveBurst DataStruct = new PDWaveBurst();
            DataStruct.fST = new float[Constants.PD_MAX_WAVEMEAS_AST];
            return DataStruct;
        }
    }
    public class Cpp_LibraryWrapper
    {
        [DllImport("cpp_library.dll")]
        public static extern int PDSetWaveSample(ref PDWaveSample pWaveSample);
        [DllImport("cpp_library.dll")]
        public static extern int PDPreProcess(int nSample, ref PDWaveBurst pWaveBurst);
    }
}

Windows窗体应用程序以以下方式使用这些功能:

我把函数简化了一点。实际上,测量值是使用第三方ActiveX组件从串行线路读取的。

using System;
using System.Configuration;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.Timers;
using System.Diagnostics;
namespace CalculationForm
{
    public partial class frmCalculationForm : Form
    {
        int nBurstSamples = 0;
        public frmCalculationForm()
        {
            InitializeComponent();
        }
        private void OnNewData_Event(object sender, Events_OnNewDataEvent e)
        {
            try
            {
                Cpp_LibraryApi.PDWaveSample WaveSampleData = Cpp_LibraryApi.PDWaveSample.Create();
                ReadWaveSample(ref WaveSampleData);
                SetWaveSample(WaveSampleData);
                if (++nBurstSamples > 512)
                {
                    // Process
                    ProcessBurstData(nBurstSamples);
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message.ToString());
            }
        }
        public void ReadWaveSample(ref Cpp_LibraryApi.PDWaveSample WaveSampleData)
        {
            float[] dVel = new float[4] { (float)-3.26, (float)-2.808, (float)-3.651, (float)-3.43 };
            ushort[] usAmp = new ushort[4] { 41, 40, 0, 0 };
            WaveSampleData.bValid = true;
            WaveSampleData.fPressure = 12.432;
            WaveSampleData.fDistance = 2.64;
            WaveSampleData.fVel = dVel;
            WaveSampleData.nAmp = usAmp;
        }
        public void SetWaveSample(Cpp_LibraryApi.PDWaveSample WaveSampleData)
        {
            Cpp_LibraryWrapper.PDSetWaveSample(ref WaveSampleData);
        }
        public void ProcessBurstData(int nSamples)
        {
            try
            {
                Cpp_LibraryApi.PDWaveBurst WaveBurstData = Cpp_LibraryApi.PDWaveBurst.Create();
                WaveBurstData.fST = new float[4096];
                WaveBurstData.fWinFloor = (float)1.25;
                WaveBurstData.fWinCeil = 2;
                WaveBurstData.bUseWindow = false;
                WaveBurstData.bSTOk = false;
                WaveBurstData.bGetRawAST = false;
                WaveBurstData.bValidBurst = false;
                Cpp_LibraryWrapper.PDPreProcess(nSamples, ref WaveBurstData);
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message.ToString());
            }
        }
    }
}

在程序进入测量处理阶段之前,一切似乎都很顺利。当

Cpp_LibraryWrapper.PDPreProcess(nSamples, ref WaveBurstData);

调用时,执行将停止,并出现以下错误:

程序"XXX.vshost.exe:Managed"已退出,代码为1073741819(0xc0000005)。

我设置了以下调试选项:

  • 启用非托管代码调试
  • 启用Visual Studio宿主进程
  • 公共语言运行时异常"抛出"
  • Win32异常->访问违规"抛出"

从C#调用非托管C++库(dll)会产生访问冲突错误(0xc0000005)

您的结构被错误地整理,因为您没有完全正确地声明数组。您需要告诉整理器它们是固定长度的数组。

编辑

在我最初的回答中,我遗漏了bool成员未正确编组的添加错误。默认编组用于4字节的Windows BOOL,但需要1字节的C++bool。下面的代码现在可以正确地处理这个问题。很抱歉造成混乱。

public struct PDWaveSample
{
    [MarshalAs(UnmanagedType.I1)]
    public bool bValid;                             
    public float fPressure;                         
    public float fDistance;                         
    [MarshalAs(UnmanagedType.LPArray, SizeConst=4)]
    public float[] fVel;
    [MarshalAs(UnmanagedType.LPArray, SizeConst=4)]
    public ushort[] nAmp
}
public struct PDWaveBurst {
    [MarshalAs(UnmanagedType.LPArray, SizeConst=4096)]
    public float[] fST;
    public float fWinFloor;
    public float fWinCeil;
    [MarshalAs(UnmanagedType.I1)]
    public bool bUseWindow;
    [MarshalAs(UnmanagedType.I1)]
    public bool bSTOk;
    [MarshalAs(UnmanagedType.I1)]
    public bool bGetRawAST;
    [MarshalAs(UnmanagedType.I1)]
    public bool bValidBurst;
}

实际上,我不得不将数组编组为ByValArray。除此之外,运行环境还有一些值得抱怨的地方:

"CalculationForm.exe 中首次出现类型为"System.TypeLoadException"的异常

其他信息:无法封送类型为"PdWaveApi"的字段"fVel"。PDWaveSample":无效的托管/非托管类型组合(数组字段必须与ByValArray或SafeArray成对出现)。"

因此,我将结构更改为:

public struct PDWaveSample
{
    [MarshalAs(UnmanagedType.I1)]
    public bool bValid;                             
    public float fPressure;                         
    public float fDistance;                         
    [MarshalAs(UnmanagedType.ByValArray, SizeConst=4)]
    public float[] fVel;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst=4)]
    public ushort[] nAmp
}
public struct PDWaveBurst {
    [MarshalAs(UnmanagedType.ByValArray, SizeConst=4096)]
    public float[] fST;
    public float fWinFloor;
    public float fWinCeil;
    [MarshalAs(UnmanagedType.I1)]
    public bool bUseWindow;
    [MarshalAs(UnmanagedType.I1)]
    public bool bSTOk;
    [MarshalAs(UnmanagedType.I1)]
    public bool bGetRawAST;
    [MarshalAs(UnmanagedType.I1)]
    public bool bValidBurst;
}