本机 C 的 C++/CLI 包装器中的 AccesViolationException

AccesViolationException in C++/CLI Wrapper for native C

我正在用 C# 编写一个应用程序,它使用 C++/CLI Wrapper .dll,它再次使用另一个 C++/CLI Wrapper 用于本机 C 代码。

进一步说明:

我的 C# 应用程序(我称之为 Reporter)只不过是一个 windows 表单,它调用第一个包含 UserControl 的 C++/CLI Wrapper(我称之为 Control)。此 UserControl 是一个 GUI,以便调用最后一个 .dll(称为 Generator)。我这样做是因为我想在其他项目中使用我的控件,并且我不想像 char *.

这样的类型编组麻烦

所以这是我的问题:有时我可以按计划调用生成器函数。但是在一些调用之后,我得到一个 AccessViolationException。

我的生成器包含大量 C 函数和全局 C 变量。一切都正确标记为 extern "C"。正如我所确定的,当我尝试使用全局变量时会发生违规。

我试图将所有全局变量放入生成器中的包装器-class,但我失败了,因为我无法将所有 C 类型转换为托管类型。

调用函数后,我 free(x) 正在 space 我的变量。在评论之前,我无法调用该函数两次以上。现在(注释掉之后)我可以调用 Generator 中的函数 4 次。总是。

我该如何解决这个问题?有没有办法像 "administrative rights" 那样提供我的函数,以允许他们使用全局变量做他们想做的事情?

提前感谢大家,我坚持了将近一个月,并且对如何编写 wrapper-classes 做了很多研究。

里昂

编辑:

这是我声明相关全局变量的方式:

"globals.h"

extern "C"{

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>  // fuer va_start, va_end
#include <string.h>
#include <malloc.h>
#include <windows.h>
//#include <omp.h>


// Used to prevent redefinition, _HAUPT_ is only defined in .dll-Header
#ifdef _HAUPT_
/*#define _HAUPT_*/
#define  TYPE

    int extreme = 0;

#else 
#define TYPE extern

    TYPE int extreme;

#endif

}

然而,当我在这里写我的编辑时,我发现问题出在我这边。我搞混了一个自己写的LinkedList,当我试图用一个值声明一个未分配的指针时发生错误

对于这样的问题,您无法得到有用的答案。访问冲突是 C 代码失败的标准方式,在该语言中有许多方法可以调用未定义的行为。破坏内存的那种,这种破坏 最终 会使您的代码崩溃。代码失败的确切位置是 非常 很少接近有错误的语句。腐败产生影响可能需要一段时间。花一个星期或更长时间来查找错误一点也不稀奇。

基本方法:

  • 编写运行 C 代码的单元测试,有助于缩小导致损坏的代码执行路径的数量。
  • 确保在打开所有调试功能的情况下构建 C 代码,默认情况下为 MSVC 编译器中的调试构建启用。您需要从 /MDd 和 /RTC 获得的所有帮助。
  • 使用 Application Verifier,一种可以检测堆损坏并向您显示导致损坏的语句的工具。最好用于失败的单元测试。
  • 想想C语言是否真的对你完成工作有用。与托管代码相比,您可以从本机代码中挤出大约 25% 的额外性能,给予或索取,但如果您不能使其可靠地工作或失去一个月的生命,那么代价是相当高的。硬件比您的工时便宜很多

我同意 Taus 的观点:

AccessViolationExceptions are most often caused by accessing freed/unallocated memory or similar. Admin rights have nothing to do with it. A minimal example would go along way towards identifying the problem

封送拆收器通常会尝试创建该数据的托管 (C#) 表示,然后尝试 deallocate/free 非托管数据 (C++)。但是,您可能没有按照编组器期望的方式在 C/C++ 中分配内存,或者您可能不希望编组器尝试为您释放内存。

如果默认的解除分配行为与您的用例不匹配,那么您可以通过在 C# 代码中使用 IntPtr 手动处理 C++ 对象的解除分配(如果有的话)。例如,如果您从非托管代码返回字符串文字,则不应释放内存。请参阅此 post 示例。

如果您 post 显示您如何在非托管应用程序中分配内存、如何公开数据以及如何在 C# 应用程序中访问它的代码片段,我们可以帮助您查明问题。