C#如何在没有编组对象的情况下将对象固定在内存中?

时间:2011-02-28 14:38:39

标签: .net pinvoke

好了,好吧,我在C#中使用oracle的ContentAccess库,该库是用C语言编写的。

我使用库的一些功能从不同的文件中提取文本。 c库使用函数指针(Delegates)的异步通信。 我有1个类和1个结构来使用这些函数,结构被称为BaseIO并包含指向我在C#中的代码读取文件的函数指针。 一切都很好,直到cli移动我的类,我得到一个MemoryAccessException。

这里是类,结构和函数签名:

[UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
public delegate DAERR CloseDelegate(IntPtr hfile);
[UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
public delegate DAERR ReadDelegate(IntPtr hfile, IntPtr dataPtr, UInt32 size, IntPtr count);
[UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
public delegate DAERR WriteDelegate(IntPtr hfile, IntPtr dataPtr, int size, IntPtr count);
[UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
public delegate DAERR SeekDelegate(IntPtr hfile, int wFrom, int dwOffset);
[UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
public delegate DAERR TellDelegate(IntPtr hfile, IntPtr dwOffset);
[UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
public delegate DAERR GetInfoDelegate(IntPtr hfile, UInt32 dwInfoId, IntPtr pInfo);
[UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
public delegate DAERR Seek64Delegate(IntPtr hfile, ushort wFrom, Int64 dwOffset);
[UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
public delegate DAERR Tell64Delegate(IntPtr hfile, Int64 dwOffset);

struct BaseIO
{
    public CloseDelegate IOCLOSEPROC;
    public ReadDelegate IOREADPROC;
    public WriteDelegate IOWRITEPROC;
    public SeekDelegate IOSEEKPROC;
    public TellDelegate IOTELLPROC;
    public GetInfoDelegate IOGETINFOPROC;
    public IntPtr IOOPENPROC;
    public Seek64Delegate IOSEEK64PROC;
    public Tell64Delegate IOTELL64PROC;
}

[StructLayout(LayoutKind.Sequential)]
class FILE
{
    public BaseIO baseIO;
    public Stream Source;
    public Stream Buffer;
}

[DllImport("sccda.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern DAERR DAOpenDocument(ref IntPtr phDoc, IOTYPE dwSpecType, FILE pSpec, DAFlags dwFlags);

DAERR是一个包含错误值的枚举。

IOTYPE是一个带有十六进制值的枚举,用于指示如何处理值pSpec。

DAFlags是一个带有十六进制值的枚举,用于指示如何处理文件(如存档,普通或自动检测)。

oke每个东西都可以运行,我的函数会在托管端被调用,但是在1次传递之后我得到一个MemoryException,表明对象已经在内存中移动了。

我不能使用编组因为我不能在我的班级中使用Stream对象而不能使用普通代理。

该库只查看FILE中的第一个对象,即结构BaseIO。

我的问题是,是否可以在没有编组对象的情况下将对象固定在内存中?

1 个答案:

答案 0 :(得分:14)

在C#中,有两种方法可以将对象固定在内存中:fixed语句和GCHandle.Alloc。在您的情况下,我相信您想要GCHandle.Alloc

有关代码示例和GCHandle.Alloc文档,请参阅fixed keyword