0

我在下面的开头用执行摘要更新了这个问题。然后,如果需要,将提供大量详细信息。感谢您的建议。

执行摘要: 我是 VS 的新手。我对一些继承的代码有疑问。代码在 VS2008 (XP64) 上构建和执行良好。相同的代码要么构建但不运行,要么无法在 XP64 或 W7 上构建 VS2008 和/或 VS2010。在更改了一些编译器选项后,我设法让它在 XP64 上的 VS2010 上运行而没有问题;但是,在 W7 上,没有运气。

我最终发现堆正在损坏。

ae312i3.3.exe 中 0x76e540f2 (ntdll.dll) 处的未处理异常:0xC0000374:堆已损坏。

我不熟悉如何考虑修复堆问题;也许现有代码中指向另一个线程或程序正在使用的内存的指针存在问题,损坏的 ntdll.dll 文件,其他?

重新启动 PC 以检查 ntdll.dll 是否已损坏并没有帮助。更改调试设置,并收到以下反馈:

HEAP[ae312i3.3.exe]:指定给 RtlSizeHeap(0000000000220000, 000000002BC8BE58) 的地址无效 Windows 已在 ae312i3.3.exe 中触发断点。

这可能是由于堆损坏,这表明 ae312i3.3.exe 或其已加载的任何 DLL 中存在错误。这也可能是由于用户在 ae312i3.3.exe 获得焦点时按 F12。

看来,当它崩溃时,C++ 正在将一个布尔变量返回到表单的表达式

While (myQueryFcn(inputvars))

  • 问题:

那么,它不是将 C++ 布尔值返回到 VB 布尔值吗?我确实相信这两者是不同的表示形式(一个使用 True/False,另一个使用整数?)这可能是一个问题吗?如果是这样,为什么它在 VB2008 中不是问题?**

或者,也许是 C++ 代码已写入分配的内存,在返回 VB 时,它崩溃了???

** 我最近了解到“Insure++”,并将尝试使用它来追踪问题。关于其使用的任何建议,其他可能的见解?**

我将不胜感激任何建议。再次感谢。

. . . . .

导致上述摘要的详细信息(如下):

我是VS2010的新手;熟悉工程应用级别的编程(Python、Fortran,但自从我广泛使用 C++ 以来已经有几十年了),但不是专业程序员。

我有一个由多个项目组成的解决方案,全部在 VS2008 中。项目是:Reader(C++ 项目;利用 3rd 方 DLL)Query(C++ 项目;取决于 Reader) Main(VB;取决于 Reader 和 Query)。

以下适用于 XP64 操作系统。 解决方案和项目是由我以外的其他人编写、构建和发布的。我已经获取了现有文件,并制作了一个副本,放在我选择的目录中,然后在 VS2010 中打开(我的 PC 上没有安装 VS2008)。我能够成功构建(尽管有很多警告 - 稍后会详细介绍);但是当我运行可执行文件时,它会到达一个点并崩溃。经过反复试验,我发现修改编译器设置为我解决了以下问题:

它将在 DEBUG 配置中构建和执行,但不是 Release。我发现在查询项目属性页/配置属性/C++/优化/优化-> 发布(x64)配置使用“最大化速度(/O2)而调试使用“禁用(/Od)”->所以我切换到'禁用(/ Od)。此外,Query 的项目属性页/配置属性/常规/整个程序优化 --> 需要设置为“使用链接时间代码生成”。

以上构建并在VS2010的XP64上运行成功。

接下来,我只是简单地复制了文件,并在装有 VS2010 的 W7 机器上放置了一份副本。 通过 2010 打开解决方案,它会自动“升级”文件。当我启动 VS2010 时,它会自动显示以下 4 个警告。他们是:

  1. 用于运算符 '&' 的 Object 类型的操作数;可能会发生运行时错误。在文件“CobraIFile.vb”中,第 1845 行,第 37 列。
  2. 完全一样的错误
  3. 通过实例访问共享成员、常量成员、枚举成员或嵌套类型;将不评估限定表达式。在文件“FileWriter.vb”中,第 341 行,第 51 列
  4. 用于运算符 '=' 的 Object 类型的操作数;使用“Is”运算符来测试对象身份。在文件'FormMain.vb'中;第 4173 行,第 32 列。

1 & 2 中的警告代码如下 ValueStr = String.Empty For iCols = 0 To DGrid.Columns.Count - 1 ValueStr &= DGrid.Item(iCols, iRows).Value & ";" // 这是警告线!!!下一个

警告 3 的代码:

    With FormMain
        WriteComment("")
        WriteComment("Generated by :")
        WriteComment("")
        WriteComment("  Program         : " & .PROGRAM.ToUpper) // THIS IS WARNING LINE!!!

警告 4 的代码:

    ' Compare material against the material table
    For iRowMat As Integer = 0 To matCount - 1
        ' Ignore new row
        If Not .Rows(iRowMat).IsNewRow Then
            ' Check material description
            // LINE BELOW IS WARNING LINE!!!
            If .Item("ColMatDesc", iRowMat).Value = matDesc Then
                DataGridMatProp.Item("ColMatIdx", iRow).Value = .Item("ColMatFile", iRowMat).Value
                Exit For
            End If ' Check description
        End If ' Check new row
    Next iRowMat

当我构建解决方案时,它将成功构建而没有错误(但有很多警告),当我运行可执行文件时,它成功加载 GUI,但在执行查询或阅读器项目时有时会崩溃(在使用 gui 执行操作后按钮)以及以下信息:

    C:\Users\mcgrete\AppData\Local\Temp\WER5D31.tmp.WERInternalMetadata.xml
    C:\Users\mcgrete\AppData\Local\Temp\WER68E6.tmp.appcompat.txt
    C:\Users\mcgrete\AppData\Local\Temp\WER722A.tmp.mdmp

我无法利用上述三个文件中的信息(不知道如何考虑这样做)。

我在 W7 中收到的警告与 XP64 中的警告非常相似/如果不完全相同;它们大致为以下类型,其中有1,600多种。添加到上面之前列出的原始 4 个警告下方的警告类型。随着我在 XP64 上而不是 W7 上的成功运行,我假设/希望这些不需要单独解决,而只是警告。

  1. 警告 C4267:'argument':从 'size_t' 转换为 'int',可能会丢失数据。C:\Users\mcgrete\Documents\iCOBRA\pts\p312\exec\win64\6111\include\atr_StringBase.h 351 1 阅读器
  2. 警告 C4018: '<' : 有符号/无符号不匹配 C:\Users\mcgrete\Documents\iCOBRA\pts\p312\exec\win64\6111\include\omi_BlkBitVectTrav.h 69 1 Reader
  3. 警告 C4244:“正在初始化”:从“双精度”转换为“浮点”,可能会丢失数据。C:\Users\mcgrete\Documents\iCOBRA\pts\p312\exec\win64\6111\include\g3d_Vector.h 76 1 阅读器
  4. 警告 C4244:“正在初始化”:从“双精度”转换为“浮点”,可能会丢失数据。C:\Users\mcgrete\Documents\iCOBRA\pts\p312\exec\win64\6111\include\g3d_Vector.h 76 1 阅读器
  5. 警告 C4800:“int”:强制值为 bool“true”或“false”(性能警告)。C:\Users\mcgrete\Documents\iCOBRA\pts\p312\exec\win64\6111\include\rgnC_Region.h 219 1 阅读器
  6. 警告 LNK4006: "public: class ddr_ShortcutImpl const & __cdecl cow_COW,struct cow_Virtual > >::ConstGet(void)const" (?ConstGet@?$cow_COW@V?$ddr_ShortcutImpl@VkmaC_Material@@@@U?$cow_Virtual@V? $ddr_ShortcutImpl@VkmaC_Material@@@@@@@@QEBAAEBV?$ddr_ShortcutImpl@VkmaC_Material@@@@XZ) 已在 ABQDDB_Odb_import.lib(ABQDDB_Odb.dll) 中定义;第二个定义被忽略 C:\Users\mcgrete\Documents\iCOBRA\pts\p312\source\312i3.3\Reader\ABQSMAOdbCore_import.lib(ABQSMAOdbCore.dll) 阅读器
  7. 警告 LNK4221:此目标文件未定义任何以前未定义的公共符号,因此任何使用此库的链接操作都不会使用它。C:\Users\mcgrete\Documents\iCOBRA\pts\p312\source\312i3.3\Reader\ABQSMAOdbCore_import.lib(ABQSMAOdbCore.dll) 阅读器
  8. 警告 C4996:“sprintf”:此函数或变量可能不安全。考虑改用 sprintf_s。要禁用弃用,请使用 _CRT_SECURE_NO_WARNINGS。详细信息请参见在线帮助。C:\Users\mcgrete\Documents\iCOBRA\pts\p312\source\312i3.3\Query\Query.cpp 271 1 查询
  9. 警告 MSB8004:输出目录不以斜杠结尾。此构建实例将添加斜杠,因为它需要允许正确评估输出目录。C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppBuild.targets 299 6 查询

现在我的求助请求:

我必须澄清一下,我愿意详细研究上面的警告;但是,我没有这样做,因为在投入这些精力并且没有编写代码开始之前,我只是想了解可能是真正的根本原因,然后将精力集中在那个方向上。

  1. 我对遇到的 XP64 问题感到失望,并且不确定是否需要对配置进行更改,或者我所做的更改是否实际上只是对未识别问题的“解决方法”?
  2. 我预计一旦 XP64 VS2010 版本的解决方案可以运行,它会毫无问题地转移到 W7,因为软件构建并在 VS2008 和 XP64 上运行良好。这是一个糟糕的假设吗?我可能会错过什么?
  3. 我应该考虑再次尝试修改配置,还是根本原因可能与上述警告有关?如果出现警告,为什么它们在 VS2008 中显然不是问题 - VS2010 中的更改是否有效地导致了实际运行时错误的产生,而在 VS2008 中我幸运地“幸免”了痛苦?

我感谢任何有关如何进行的指导和见解,因为根据我有限的经验,从网络上的搜索来看,VS2010 中存在许多编译器错误或相关错误。不确定是否有任何与我的问题有关,如果大量警告实际上是一个问题并且代码需要大量清理,或者是否只是一些我可能必须处理的配置问题。

仅供参考 - 我安装的 VS2010 的最新更新/SP 是 VS10SP1-KB2736182.exe。我也尝试过使用调试器,但无法让它在我的 Query 或 Reader 项目代码中的断点处停止,即使在以管理员身份运行 VS2010 时也是如此。W7 确实安装了 .NET Framework 4.0 多目标包,并且我的解决方案配置为使用 .NET Framework 4.0 客户端配置文件。

提前致谢!

更新 2013 年 3 月 18 日 我不知道如何回答我自己的问题,所以这里有一个更新。

我仍然无法让调试器工作;所以,我用老式的方式来做——添加了各种 MessageBox 来找到它崩溃的地方。A. Main.vb 程序调用 'Query' 项目中的函数

OdbQueryGetIncrement(str_out, vec_ptr)

B. 然后,函数 100% 执行,试图返回一个布尔值......这是添加了一些老式调试代码的代码......

    //Gets the next item in a list.
    // Returns false if there is the vector is empty.
    // NOTE: Once an element is returned it is removed from the list.
    bool __stdcall OdbQueryGetItem(
                    char* &str_out,  // RETURN Next item in list.
            void * vec_ptr, // Pointer to the vector of pointers.
            int index)  // Index of pointers vector to return next item of.
    {
        // Cast the point into an array of pointers
        std::vector<std::string>* *vec_temp = (std::vector<std::string>* *) vec_ptr;
        bool bool_out = false;

        char vectempsize[1000];
        int TEM1;
        char temp[1000];
        TEM1 = vec_temp[index]->size();
        // Check vector is valid
        if (vec_temp) {
            if(vec_temp[index]->size() >= index)
            {
                sprintf(temp,"value: %d\n",(int)bool_out);
                ::MessageBoxA(0, (LPCSTR) temp, (LPCSTR) "OdbQuery.dll - bool_out", MB_ICONINFORMATION);
                sprintf(temp,"value: %d\n",(int)index);
                ::MessageBoxA(0, (LPCSTR) temp, (LPCSTR) "OdbQuery.dll - index", MB_ICONINFORMATION);
                sprintf(vectempsize,"value: %d\n",(int)TEM1);
                ::MessageBoxA(0, (LPCSTR) temp, (LPCSTR) "OdbQuery.dll - index", MB_ICONINFORMATION);
            }

            if (!vec_temp[index]->empty()) {
                // Get the next item in the list
                std::string item = vec_temp[index]->front();
                // Initialise ouput string
                str_out = (char*)malloc( item.size()*sizeof(char) );
                sprintf(str_out, "%s", item.c_str());

                ::MessageBoxA(0,(LPCSTR) str_out, (LPCSTR) "hello", 0);
                // Remove first item from the vector
                vec_temp[index]->erase(vec_temp[index]->begin());
                bool_out = true;
            }
        }

      sprintf(temp,"value: %d\n",(int)bool_out);
      ::MessageBoxA(0, (LPCSTR) temp, (LPCSTR) "OdbQuery.dll - bool_out", MB_ICONINFORMATION);
      return bool_out;
    }

代码按预期以 bool_out=false 开头(使用 MessageBox 值 = 0 输出验证) 代码读取并输出带有 MessageBox 的 index = 2... 代码读取并输出 TEM1=vec_temp[index]->size() 为带有 MessageBox 的 value=2... 代码将 bool_out 输出为带有 MessageBox 的 true (value=1)... 然后,代码崩溃。在调用上述代码的行之后放置的 MessageBox 永远不会被执行。VS2010 的输出是“程序'[6892] ae312i3.3.exe: Managed (v4.0.30319)' has exited with code -2147483645 (0x80000003).”

我不知道为什么从这个函数返回时执行会死掉。编译器设置或错误是否存在一些可能的问题?

任何帮助表示赞赏!

更多信息

您好,我修改了属性页面上的一些设置,试图让调试器给我更多信息。这导致更多信息如下:

ae312i3.3.exe 中 0x76e540f2 (ntdll.dll) 处的未处理异常:0xC0000374:堆已损坏。

我不熟悉如何考虑修复堆问题;也许现有代码中指向另一个线程或程序正在使用的内存的指针存在问题,损坏的 ntdll.dll 文件,其他?

我将尝试重新启动 PC 以查看是否有帮助,尽管我对此没什么希望……没有帮助。

在调试器中找到“启用非托管代码调试”选项,检查它;清洁;重建; 运行调试...

输出更具描述性——

HEAP[ae312i3.3.exe]:指定给 RtlSizeHeap(0000000000220000, 000000002BC8BE58) 的地址无效 Windows 已在 ae312i3.3.exe 中触发断点。

这可能是由于堆损坏,这表明 ae312i3.3.exe 或其已加载的任何 DLL 中存在错误。这也可能是由于用户在 ae312i3.3.exe 获得焦点时按 F12。

看来,当它崩溃时,C++ 正在将一个布尔变量返回到表单的表达式

While (myQueryFcn(inputvars))

那么,它不是将 C++ 布尔值返回到 VB 布尔值吗?我确实相信这两者是不同的表示形式(一个使用 True/False,另一个使用整数?)这可能是一个问题吗?如果是这样,为什么它在 VB2008 中不是问题?

4

1 回答 1

0

我解决了自己的问题;问题的根本原因如下。

根本原因:

  1. VisualBasic (VB) 称为 C++。

  2. VB 创建一个字符串并发送到 C++。以前的开发人员/编码人员在 C++ 中为相同的字符串分配了内存。

  3. 当 C++ 代码执行结束时,C++ 似乎已经终止了 VB 和 C++ 建立的内存分配。

解决方案: 1. 删除 C++ 代码中的内存分配(下)。

str_out=(char*)malloc( (item.size()+1)*sizeof(char) );
  1. 修改 VB 代码以使用 StringBuilder 类型,而不是字符串。

    将 str_out 调暗为 StringBuilder = 新 StringBuilder(5120)

请参阅:从 c++ 函数返回字符串到 VB .Net

于 2013-04-22T13:06:39.503 回答