2011-02-28 10 views
7

Ok aquí va, estoy usando la biblioteca de Oracle ContentAccess en C#, la biblioteca está programada en C.C# ¿Cómo puedo fijar un objeto en la memoria sin ordenar el objeto?

Utilizo algunas funciones de la biblioteca para extraer texto de diferentes archivos. la biblioteca c usa la comunicación asincrónica por punteros de funciones (Delegados). tengo 1 clase y 1 estructura que se necesita para usar las funciones, la estructura se llama BaseIO y contiene punteros de funciones que apuntan a mi código en C# para leer archivos. todo está bien, hasta que cli mueva mi clase, y obtengo una MemoryAccessException.

aquí es la clase, estructura y función de la firma:

[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 es una enumeración con valores de error.

IOTYPE es una enumeración con valores hexadecimales para indicar qué hacer con el valor pSpec.

DAFlags es una enumeración con valores hexadecimales para indicar cómo tratar el archivo (como un archivo, normal o autodetectar).

oke todo funciona, y mis funciones se llaman en el lado administrado como debería, pero después de 1 pase obtengo una MemoryException que indica que el objeto se ha movido en la memoria.

No puedo usar referencias porque no puedo usar un objeto Stream en mi clase y no puedo usar delegados normales.

La biblioteca solo mira el primer objeto en FILE y esa es la estructura BaseIO.

Mi pregunta es, ¿es posible fijar un objeto en la memoria sin ordenar el objeto?

Respuesta

11

En C#, hay dos maneras de fijar un objeto en la memoria: la instrucción fixed y GCHandle.Alloc. En su caso, creo que quiere GCHandle.Alloc.

Consulte GCHandle.Alloc para obtener un ejemplo de código y la documentación fixed keyword.

Cuestiones relacionadas