Utilice la fixed
declaración:
fixed (double* aaPtr = aa) {
// You can use the pointer in here.
}
Mientras que en el contexto de fixed
, se fija la memoria para la variable de modo que el recolector de basura no va a tratar de moverlo.
me gustaría tener este enfoque en su lugar:
public class EigenSolver
{
public double[] _aa;
/*
There really is no reason to allow callers to pass a pointer here,
just make them pass the array.
public EigenSolver(double* ap)
{
aPtr = ap;
}
*/
public EigenSolver(double[] aa)
{
_aa = aa;
}
public void Solve()
{
unsafe {
fixed (double* ptr = _aa) {
Interop.CallFortranCode(ptr);
}
}
}
}
esto supone de CallFortranCode supuesto no trate de usar el puntero fuera de la llamada. Una vez que la declaración fijo se sale del ámbito del puntero ya no es válida ...
ACTUALIZACIÓN:
No hay ninguna manera se puede tomar la dirección de su argumento double[] aa
y lo almacena en su campo de instancia. Incluso si el compilador le permitiera, el GC está obligado a mover esa memoria dejando su puntero inútil.
Probablemente pueda hacer esto: use Marshal.AllocHGlobal para asignar suficiente memoria para almacenar todos los elementos de la matriz (aa.Length * sizeof(double))
). A continuación, utilice Marshal.Copy para copiar el contenido de la matriz a la memoria recién asignada:
bool _ownsPointer;
public EigenSolver(double[] aa) {
IntPtr arrayStore = (double*)Marshal.AllocHGlobal(aa.Length * sizeof(double));
Marshal.Copy(aa, 0, arrayStore, aa.Length);
this.aPtr = (double*)arrayStore.ToPointer();
_ownsPointer = true;
}
~EigenSolver {
if (_ownsPointer) {
Marshal.FreeHGlobal(new IntPtr(this.aPtr));
}
}
Esperamos que esto funciona ...
Andrew
Bien, ¿entonces debería hacer algo en el método 'Solve'? – Graviton
Tendré que mantener ambas sobrecargas del constructor para fines de interfaz. Así que no puedo hacer que la propiedad cambie como lo hace – Graviton
Quizás debería expresarme más claramente. Lo que quiero decir es que no puedo cambiar el tipo '_aa' de puntero a matriz. Entonces la solución anterior no funcionará. – Graviton