【问题标题】:Unmanaged c++ code causes crashes to .Net application非托管 c++ 代码导致 .Net 应用程序崩溃
【发布时间】:2012-10-31 13:20:46
【问题描述】:

我知道这里有一些线程被问到同一主题,但不幸的是没有一个对我有帮助。

我在我的 .net 应用程序中使用非托管 c++ 代码的包装器,在非托管 Dll 中有一个函数“LoadLayoutFile()”,它加载一个带有扩展名 (.lyt) 的自定义格式文件,我的 .net 应用程序有一个循环,它根据数组项计数调用该函数。如果这个数组有一个项目,应用程序运行顺利,没有任何问题,但是如果它有多个项目,应用程序立即崩溃,当然,没有任何机会弄清楚发生了什么,但这也不是所有的时间也是,这非常令人困惑。

我尝试使用 DebugDiag、Windbg 来跟踪崩溃,但没有成功。 我还尝试通过添加析构函数、异常处理来修复我的非托管代码,我还尝试将垃圾收集器(在 .net 应用程序中)放在它们应该在的位置,但这些都不起作用。我很想知道发生了什么事?或者至少能够发现错误!

这是 c++ dll 中的 LoadLayoutFile():

int CMKCRD32App::LoadLayoutFile(LPCSTR lpszFileName)
{
    try
    {
        int     nRetVal = MCRC_SUCCESS;
        CFile   file;
        WORD    wVersionNumber;

        // Add New Layout to the Layouts List
        nRetVal = AddLayout();

        // If Layout not added Correctly return Error Code
        if(nRetVal<0)
            return MCRC_MAXLAYOUT_REACHED;

        if(file.Open(lpszFileName,CFile::modeRead|CFile::shareCompat))
        {
            CArchive    ar(&file,CArchive::load);

            ar >> wVersionNumber;

            m_pCard[nRetVal]->Serialize(ar,wVersionNumber);

            ar.Close();
            file.Close();

            m_pCard[nRetVal]->OffsetItemsByMargin(TRUE);
        }
        else
        {
            nRetVal = MCRC_ERROROPENFILE;
        }

        return nRetVal;
    }
    catch(char *str)
    {
        throw str;
    }
}

AddLayout()

int CMKCRD32App::AddLayout()
{
    int nIndex;
    try
    {
        for(nIndex=(_MAX_LAYOUTS_-1); nIndex >= 0; nIndex--)
            if(m_pCard[nIndex]==NULL)
                break;

        if(nIndex>=0)
        {
            m_pCard[nIndex] = new CLYT_Card();

            if(!m_pCard[nIndex])
            {
                nIndex = -1;
            }
        }

        return nIndex;
    }
    catch(char *str)
    {
        throw str;
    }

}

这里正是它在 .net 应用程序中崩溃的地方(有时):

CardLayout cardLayout = new CardLayout(); // Wrapper

foreach(var item in x)
   int layout = cardLayout.LoadLayoutFile("cc.lyt");

【问题讨论】:

  • LoadLayoutFile 的 p/invoke 签名是什么样的?还有应用程序是如何崩溃的?你是遇到异常还是什么?
  • @PatrickQuirk 签名是extern "C" extern int WINAPI MC_LoadLayoutFile(LPCSTR lpszFileName) { CHECK_PROTECT_NOKEY_BOOL; return theApp.LoadLayoutFile(lpszFileName); } 没有例外,只是崩溃,它就消失了!
  • 您使用的是哪个 IDE?在 VS 中,您可以将调试模式设置为“混合”,这样您就可以调试本机代码和托管代码。
  • 您能否展示一下 pinvoke 的 C# 端,您在其中定义了一个带有 DllImport 属性的 extern 方法?
  • @PatrickQuirk 是的……[DllImport("MC32.dll")] public static extern int MC_LoadLayoutFile(string lpszFileName);

标签: c# c++ crash unmanaged


【解决方案1】:

您的库看起来不错,可能是性能问题,您可能有很大的堆栈跟踪。如果你调用它一次时它没有崩溃,并且当你调用它时它确实崩溃了(有时就像你说的那样),那可能是因为内存中有巨大的对象,特别是如果你的库有一些图像处理工作要做(我假设那是因为我看到了layout 文件)并且它没有正确地销毁它们。

我对您的建议是尝试将您的桌面应用程序代码与调用该库的部分分开,您可能应该尝试让它在另一个线程上工作,或者尝试将该代码段放在控制台应用程序中并调用它控制台应用程序与您的桌面应用程序,这将使它们彼此分开,如果可能发生任何崩溃,它不会影响您的桌面应用程序。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-28
    相关资源
    最近更新 更多