Ладно, я использую библиотеку 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.
У меня вопрос: возможно ли закрепить объект в памяти без маршалинга объекта?