Pregunta

Estoy teniendo un momento muy difícil conseguir este cálculo de referencias hacia abajo.

Tengo código umanaged que es similar al siguiente:

WORD HLP_GetDeviceNames (LPSTR *DevNames, WORD Max_Len, WORD Max_Num)

Lo digo que no escribió el código no administrado, sino que debe usarlo.

Las devoluciones:. PALABRA que indica un error

DEVNAMES: Puntero a una matriz de matrices de carbonilla. Básicamente una matriz de cadenas que será modificado y volvió de nuevo a mí!

max_len: La longitud de cada cuerda (me han dicho que esto debe ser 256)

MAX_NUM: Duración de la matriz. Estoy usando otra llamada de invocación que está trabajando que me dice número de dispositivos, así que sé exactamente cuántas cadenas para enviar.

He utilizado signatureToolkit P / Invoke interoperabilidad con la figura montón de esto, sino también leer un montón de conseguir aún más. Donde estoy ahora está aquí:

[DllImport("UsbMeasLib.dll")]
public static extern ushort HLP_GetDeviceNames([MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPStr)] ref StringBuilder[] DevNames, ushort Max_Len, ushort Max_Num);

Me llamo mi código como el siguiente:

StringBuilder[] DevNames = new StringBuilder[deviceCount];
     for(int i = 0; i< deviceCount; i++)
     {
           DevNames[i] = new StringBuilder().Append(' ', 256);
     }

     HachUsbMeasLib.HLP_GetDeviceNames(ref DevNames, 256, Convert.ToUInt16(DevNames.Count())); 

Estoy utilizando la matriz constructor de cadena porque necesito el código no administrado a modificar el constructor de cadena para que pueda devolver la nueva cadena desde la cadena es unmutable.

Al ejecutar el código, Mi matriz es modificada!

No estoy realmente seguro de lo que está pasando, pero creo que tiene algo que ver con CLR contando código no administrado a no modificar mi arsenal en su lugar sino que crea una nueva referencia (puntero). Incluso si este es el caso, no sé cómo solucionarlo.

Gracias por cualquier idea de que nadie puede ofrecer!

¿Fue útil?

Solución 2

pensé éste hacia fuera. Gracias a todo el que respondió.

Me enteré de cómo funciona. Simplemente suministrar el espacio de memoria, pero tengo que dejar que los conocimientos de cálculo de referencias que espero dentro y fuera con este objeto, de manera que permite que el código no administrado a modificar el espacio asignado.

Lo hice así:

[DllImport("UsbMeasLib.dll")]
private static extern ushort HLP_GetDeviceNames([In, Out, MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPStr)] string[] DevNames, ushort Max_Len, ushort Max_Num);

Yo uso de cadenas en lugar de la cadena de constructor porque el código no administrado simplemente reemplazar la cadena, que está bien. Me estoy haciendo la parte posterior puntero de la lista, las cadenas no modificados. el código administrado sólo está cambiando un vector de punteros a punto de nuevos objetos de cadena (creo).

int numDev = HLP_GetNumDevices();


string[] names = new string[numDev];

for (int i = 0; i < names.Length; i++)
{
    names[i] = new StringBuilder().Append(' ', 256).ToString();
}

ushort errorCode = HLP_GetDeviceNames(names, 256, Convert.ToUInt16(numDev));

Asignar memoria para el código unamanged luego dejar que el código no administrado chane las cuerdas allí.

Este obras pero no sé si tengo pérdidas de memoria potenciales u otros problemas potenciales.

Otros consejos

Trate de trabajar en un nivel bajo. parámetro DEVNAMES declarar como IntPtr []. Prepararlo por la siguiente manera:

IntPtr[] devNames = new IntPtr[deviceCount];

for(int i = 0; i < deviceCount; i++) 
{ 
    devNames[i] = Marshal.AllocHGlobal[256];
}

Pase esta matriz a HLP_GetDeviceNames. Para manejar los datos de salida, se aplican a todos los miembros Marshal.PtrToStringAnsi DEVNAMES. No se olvide de liberar DEVNAMES [i] con Marshal.FreeHGlobal al final.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top