C # Как я могу закрепить объект в памяти, не распределяя объект? - PullRequest
9 голосов
/ 28 февраля 2011

Ладно, я использую библиотеку ContentAccess оракула в C #, библиотека запрограммирована на 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 - это перечисление с шестнадцатеричными значениями, указывающими, как обрабатывать файл (например, архив, нормальный или автоопределение).

все работает, и мои функции вызываются на управляемой стороне, как и должно, но через 1 проход я получаю исключение MemoryException, указывающее, что объект был перемещен в память.

Я не могу использовать маршаллинг, потому что тогда я не могу использовать объект Stream в своем классе и не могу использовать обычные делегаты.

Библиотека просматривает только первый объект в FILE, и это структура BaseIO.

У меня вопрос: возможно ли закрепить объект в памяти без маршалинга объекта?

1 Ответ

14 голосов
/ 03 апреля 2011

В C # есть два способа закрепить объект в памяти: оператор fixed и GCHandle.Alloc. В вашем случае, я полагаю, вы хотите GCHandle.Alloc.

См. GCHandle.Alloc для примера кода и исправленного ключевого слова документации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...