3

我有一些在 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)
4

3 回答 3

2

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

于 2009-05-03T23:59:40.853 回答
1

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

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

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

于 2009-05-04T07:31:00.753 回答
0

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

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

于 2009-05-04T01:05:30.443 回答