调用非托管 C++ C# 中的库 (dll) 创建访问冲突错误 (0xc0000005)

发布于 2024-11-16 20:29:25 字数 16918 浏览 0 评论 0原文

抱歉问了这么长的问题。我只是想包括我目前所知道的有关该问题的所有信息。

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

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

程序“XXX.vshost.exe:托管”已退出,代码为-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:托管”已退出,代码为 -1073741819 (0xc0000005)。

我设置了这些调试选项:

  • 启用非托管代码调试
  • 启用 Visual Studio 托管进程
  • 公共语言运行时异常 “抛出”
  • Win32 异常 ->访问冲突“抛出”

Sorry for the long question. I just wanted to include everything that I know about the problem at the moment.

I'm using Visual Studio 2008 to create a Windows Form program in C# that calls a library written in C++.
The C++ DLL analyzes measurement data, which consists of several samples. The samples are passed to the library by a function (PDSetWaveSample) which takes a struct as a parameter.
After all samples are set, the measurement data is processed with another function (PDPreProcess) which also takes a struct as a parameter.
The C++ DLL is holding all the measurement data in its internal data structures and does all the processing to obtain results.

Everything seems to function correctly until the program starts processing the measurement data. At that point the program crashes and exits with this error:

The program 'XXX.vshost.exe: Managed' has exited with code -1073741819 (0xc0000005).

I’ll add some more debugging information and the C# source code later in this question.

Do you have any hints how to go forward or what probably could cause this?

I am running Windows XP Professional, Version 2002 SP 3.

When the program crashes, it first gives this error message

An unhandled exception of type 'System.ExecutionEngineException' occurred in Unknown Module.

and the possibility to Break or Continue. I choose to Break.

After that I look at the assembly:

No symbols are loaded for any call stack frame. The source code cannot be displayed.

According to the debugger, the assembly at the point where the error happens looks like this:

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           

The execution stops at 7C90E514 ret (which I marked with ==>)

The output window shows the following messages:

'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).

When program ends, the call stack is:

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()     

I have created a wrapper class for the C++ DLL. The wrapper class is based on the header file for the library:

#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);

and the C# wrapper class is:

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);

    }
}

The Windows Forms application is using these functions in the following way:

I have simplified the function a little bit. Actually the measurements are read from a serial line using a third party ActiveX component.

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());
            }
        }
    }
}

Everything seems to go well until the program reaches the measurement processing phase. When

Cpp_LibraryWrapper.PDPreProcess(nSamples, ref WaveBurstData);

is called, the execution stops with this error:

The program 'XXX.vshost.exe: Managed' has exited with code -1073741819 (0xc0000005).

I have set these debugging options:

  • Enable unmanaged code debugging
  • Enable the Visual Studio hosting process
  • Common Language Runtime Exceptions “Thrown”
  • Win32 Exceptions -> Access violation “Thrown”

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

像你 2024-11-23 20:29:25

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

编辑

在我原来的答案中,我错过了 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;
}

Your structs are marshalled incorrectly because you didn't declare the arrays quite right. You need to tell the marshaller that they are fixed length arrays.

EDIT

In my original answer I missed the addition error that the bool members were not marshalled correctly. The default marshalling is for the 4 byte Windows BOOL but you need 1 byte C++ bool. The code below now handles that correctly. Sorry for the confusion.

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.PDWaveSample’类型的字段‘fVel’:无效的托管/非托管类型组合(数组字段必须与 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;
}

Actually, I had to marshall the arrays as ByValArray. Otherwise the running environment had something to complain about:

"A first chance exception of type 'System.TypeLoadException' occurred in CalculationForm.exe

Additional information: Cannot marshal field 'fVel' of type 'PdWaveApi.PDWaveSample': Invalid managed/unmanaged type combination (Arrays fields must be paired with ByValArray or SafeArray)."

So, I changed the struct to this:

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文