CLR 干扰 C++ 性病?

发布于 2024-07-20 01:11:34 字数 2631 浏览 3 评论 0原文

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

我的 common.h 文件包含我需要的所有 std 库标头。 它包含在 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)

I have some code compiling under the clr and other code that is unmanaged in a single project.

My common.h file includes all the std library headers that I need. It is included by manager.h (forward declaration for manager.cpp (no CLR)), which is included by main_window.h (WinForm) which is included by document_manager.cpp (CLR).

At runtime I get all sorts of weird behavior, in one instance, my form wouldn't load. Pausing the program for debugging several times showed that it was stuck reallocating memory for a std::string, in malloc.c. By changing the code, I can recieve a System::InvalidMemory (I think) exception in ostream.

How do I stop the CLR from managing the std library?

If anyone would like the source to any of my files, just ask.

Edit:
In the callstack, I have some managed code that runs when my form loads. In the window init callback, I have a managed to native transition, and then my manager class. Later on, I get to

    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;

and the callstack shows std::basic_string::assign, then some other std:: functions, and finally the malloc function, which it is perpetually stuck in.

Edit:
The exception that is thrown on file writing:

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)

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

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

发布评论

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

评论(3

桜花祭 2024-07-27 01:11:34

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

Have you tried wrapping #pragma unmanaged / #pragma managed around the functions you need to stay unmanaged? While written in a kind of "breathless enthusiasm" tone, http://www.ondotnet.com/pub/a/dotnet/2003/03/03/mcppp2.html does have some tips on mixing managed and unmanaged code/objects.

﹉夏雨初晴づ 2024-07-27 01:11:34

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

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

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

I think you might be hit by the One Definition Rule, from your description. In C++, you are allowed to have multiple definitions for a class, but they should all be identical. This allows you to put class definitions in headers.

You still have to be careful with the "identical" part. This doesn't mean just the tokens in the source code, but their replacement after the prceprocessor and (in practice) the meaning of them given the current compiler settings. A clear example would be the 32/64 bit switch, or the alignment setting - those could change the sizeof of a class.

In your case, you might have two definitions of the Microsofts STL classes, under different settings.

樱桃奶球 2024-07-27 01:11:34

只是盲目尝试,但请尝试关闭对正在使用 STL 的 CPP 文件的 CLR 支持。这个问题展示了如何对单个 CPP 文件执行此操作。 它有效地本地编译它们。

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

Just a shot in the dark, but try turning off CLR support for the CPP files that you are using STL in. This question shows how to do that for individual CPP files. It effectively compiles them natively.

Fair warning: if you go this route, you may have to turn off precompiled headers the CPP files you compiled natively.

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