C#受保护的内存问题

时间:2011-08-24 22:50:37

标签: c# c++ pinvoke

我是PINvoking本机C ++ DLL。实际上我已经完成了两次(两个不同的C#程序,两个不同的C ++程序)。两次我都在C#端创建内存。两次我使用相当复杂的编组结构,我通过参考发送。

然而,我的一个程序运行得很好。

另一个运行直到本机C ++尝试从发送的数据中读取值。但是然后爆炸,我遇到了读/写保护内存错误?

我不明白使用同一个Visual Studio构建的两个程序如何能够让我访问内存而另一个禁止访问。

我检查了设置,两者在项目设置中几乎完全相同?

在我遇到问题的项目中,我甚至将发送的数据减少到如此大小的结构:

[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
struct Shared2_s
{
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
    public byte[] filler2;
    //40
}

2 个答案:

答案 0 :(得分:1)

如果您需要Shared2_s实例的生命周期长于对本机方法的调用,则需要在非托管内存中分配它并在完成后再次清理它。

var pointer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Shared2_s)));
var inst = new Shared2_s();
Marshal.StructureToPtr(inst, pointer, false);
...
MyNativeMethod(pointer);
...
Marshal.FreeHGlobal(pointer);

应该调整MyNativeMethod的DllImport声明,以便取代ref Shared2_s参数,而不是IntPtr

在确定没有其他本机代码会尝试访问已分配的内存后,您应该只调用FreeHGlobal。

答案 1 :(得分:0)

对于这种东西,我使用MemoryMappedFile和一个名为Mutex - 没有涉及编组,只有内存中的一些字节,任何具有正确权限和知识的人都可以读取/写入MemoryMappedFile的名称。

[编辑] 对于C ++方面,请参阅MSDN示例here。的 [/编辑]