【问题标题】:CLR interfering with C++ STD?CLR 干扰 C++ STD?
【发布时间】:2010-10-23 12:45:42
【问题描述】:

我有一些在 clr 下编译的代码和其他在单个项目中不受管理的代码。

我的 common.h 文件包含我需要的所有标准库头文件。它包含在 manager.h(manager.cpp(无 CLR)的前向声明)中,它包含在 main_window.h(WinForm)中,而 main_window.h(WinForm)包含在 document_manager.cpp(CLR)中。

在运行时,我会遇到各种奇怪的行为,在一种情况下,我的表单无法加载。暂停程序进行多次调试表明它在 malloc.c 中为 std::string 重新分配内存时卡住了。通过更改代码,我可以在 ostream 中收到 System::InvalidMemory(我认为)异常。

如何阻止 CLR 管理 std 库?

如果有人想要我的任何文件的来源,请询问。

编辑: 在调用堆栈中,我有一些在我的表单加载时运行的托管代码。在窗口初始化回调中,我有一个管理到本机的转换,然后是我的管理器类。稍后,我会去

    std::string error_msg;
    error_msg = "Storage Manager: SQLite Error ("; <-- Executing Currently
    error_msg += sqlite3_errcode(this->db_p);
    error_msg += ") - ";
    error_msg += sqlite3_errmsg(this->db_p);
    *(this->log) << error_msg.c_str() << std::endl;

调用堆栈显示 std::basic_string::assign,然后是其他一些 std:: 函数,最后是 malloc 函数,它永远卡在其中。

编辑: 写入文件时抛出的异常:

System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
   at manager.file_open(manager* , basic_string<char\,std::char_traits<char>\,std::allocator<char> >* )
   at DocumentManager.main_window.file_open_mainmenu_Click(Object sender, EventArgs e) in c:\development\document manager\document manager\main_window.h:line 456
   at System.Windows.Forms.ToolStripItem.RaiseEvent(Object key, EventArgs e)
   at System.Windows.Forms.ToolStripMenuItem.OnClick(EventArgs e)
   at System.Windows.Forms.ToolStripItem.HandleClick(EventArgs e)
   at System.Windows.Forms.ToolStripItem.HandleMouseUp(MouseEventArgs e)
   at System.Windows.Forms.ToolStripItem.FireEventInteractive(EventArgs e, ToolStripItemEventType met)
   at System.Windows.Forms.ToolStripItem.FireEvent(EventArgs e, ToolStripItemEventType met)
   at System.Windows.Forms.ToolStrip.OnMouseUp(MouseEventArgs mea)
   at System.Windows.Forms.ToolStripDropDown.OnMouseUp(MouseEventArgs mea)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
   at System.Windows.Forms.ToolStrip.WndProc(Message& m)
   at System.Windows.Forms.ToolStripDropDown.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

【问题讨论】:

  • 你能发布一些重现问题的代码吗?一些更具体的错误也可能会有所帮助。如果您甚至不确定引发了哪个异常,或者从哪里引发了异常,那么调试将变得非常困难。
  • 以上信息够用吗?我在简单地重现问题时遇到了一些麻烦 - 但我会坚持下去。
  • 为什么投反对票?这是个好问题。 +1

标签: c++ visual-studio clr std


【解决方案1】:

您是否尝试过将#pragma unmanaged / #pragma managed 包装在您需要保持非托管状态的函数周围? http://www.ondotnet.com/pub/a/dotnet/2003/03/03/mcppp2.html 虽然以一种“令人窒息的热情”的语气写成,但确实有一些混合托管和非托管代码/对象的技巧。

【讨论】:

  • @LithMaster,将 Alex 的建议与我的答案结合起来,这应该不会导致 CLR 控制您想要本地运行的 CPP 文件。
【解决方案2】:

根据您的描述,我认为您可能会受到单一定义规则的影响。在 C++ 中,一个类可以有多个定义,但它们都应该相同。这允许您将类定义放在标题中。

您仍然必须小心“相同”部分。这不仅仅意味着源代码中的标记,还意味着它们在 prceprocessor 之后的替换以及(在实践中)它们在当前编译器设置下的含义。一个明显的例子是 32/64 位开关,或者对齐设置 - 这些可以改变一个类的 sizeof。

在您的情况下,您可能在不同的设置下有两个 Microsoft STL 类的定义。

【讨论】:

  • 我不完全明白你的意思。我有一个包含 和所有其他 STD 库的文件,并且在它的顶部有一个“#pragma once”——这是你的意思吗?
  • 您误解了 C++ 编译规则。从技术上讲,您不需要编译 .cpp 文件。您编译每个预处理器输出(“翻译单元”)。包含两次的头文件是两个不同翻译单元的一部分,其中的定义被编译两次 - 可能使用不同的设置。
【解决方案3】:

只是在黑暗中拍摄,但请尝试关闭对您正在使用 STL 的 CPP 文件的 CLR 支持。This question 展示了如何对单个 CPP 文件执行此操作。它有效地在本地编译它们。

公平警告:如果你走这条路,你可能必须关闭你本地编译的 CPP 文件的预编译头文件。

【讨论】:

  • 在发布这个问题之前我已经这样做了。我为 cpp 文件启用了 CLR 支持,并且我克服了我的问题点。现在,我遇到了一个无法为其启用 CLR 的文件 sqlite.c 的问题。编译器不允许我,因为它是 C,而不是 C++,并且将其编译为 C++ 会给我带来大量错误。
  • 只是为了澄清一下,当我启用 clr 支持时,我的程序的那部分工作正常。我收到一个异常:Document Manager.exe 中发生了“System.AccessViolationException”类型的未处理异常附加信息:尝试读取或写入受保护的内存。这通常表明其他内存已损坏。
  • 嗯,让我考虑一下 - 我希望你能解决它!
  • 更多测试表明,当我到达问题中显示的错误处理程序时,我认为抛出了异常,但它在 WinForms 后端代码中的某处被捕获。如果我在代码中的每一行都放置一个断点,在一个错误处理程序调用的区域中,错误处理程序调用之后的断点什么都不做,程序继续运行。
猜你喜欢
  • 1970-01-01
  • 2016-08-21
  • 2017-10-15
  • 1970-01-01
  • 2020-04-08
  • 2015-02-09
  • 2012-07-17
  • 2019-06-17
  • 2015-02-12
相关资源
最近更新 更多