【发布时间】:2009-12-06 00:19:10
【问题描述】:
第一层
我有一个用 VC++6 service pack 6 编写的 win32 dll。让我们将此 dll 称为 FirstLayer。我无权访问 FirstLayer 的源代码,但我需要从托管代码中调用它。问题是 FirstLayer 大量使用 std::vector 和 std::string 作为函数参数,并且无法将这些类型直接编组到 C# 应用程序中。
第二层
我能想到的解决方案是先创建另一个用VC++6 service pack 6编写的win32 dll。我们把这个dll称为“SecondLayer”。 SecondLayer 充当 FirstLayer 的包装器。该层包含 std::vector 的包装类,因此 std::vector 不会在该层的所有函数参数中公开。我们将 std::vector 的这个包装类称为 StdVectorWrapper。
该层不使用任何新的或删除的操作来分配或释放内存,因为这是由 std::vector 内部处理的。
第三层
我还创建了一个 VC++2005 类库作为 SecondLayer 的包装器。这个包装器完成了将非托管 SecondLayer 转换为托管代码的所有繁琐工作。让我们将此层称为“ThirdLayer”。
与SecondLayer类似,该层在处理StdVectorWrapper时不使用new和delete。
第四层
最重要的是,我创建了一个 C#2005 控制台应用程序来调用 ThirdLayer。我们将这个 C# 控制台应用程序称为“FourthLayer”。
调用序列摘要
FourthLayer(C#2005) -> ThirdLayer(VC++2005) -> SecondLayer(VC++6) -> FirstLayer(VC++6)
问题
我注意到“System.AccessViolationException: Attempted to read or write protected memory”异常被抛出,我怀疑这是由于 SecondLayer 的内部 std::vector 分配内存是非法的第三层访问。
我认为这得到了证实,因为当我在 VC++2005 中重新编译 FirstLayer(模拟)和 SecondLayer 时,问题完全消失了。但是,由于我没有源代码,无法重新编译 FirstLayer 的生产版本。
我听说为了解决这个问题,我需要用 C++ 为 SecondLayer 的 std::vector 编写一个共享内存分配器,它位于 StdVectorWrapper 类中。我不完全理解为什么我需要一个共享内存分配器以及它是如何工作的?有什么想法吗?
互联网上是否有任何现成的源代码可以编译并与我在 SecondLayer 中的代码一起使用?
请注意,我无法为此使用 boost 库。
【问题讨论】:
-
忘记我的第一个答案。这是错误的。
标签: c++ memory dll stl shared-memory