Domanda

Stavo usando la funzione strlen da msvcrt.dll in un progetto di 3,5 .Net. Più in particolare:

private unsafe static extern int strlen( byte *pByte );

Dopo la migrazione a .NET 4.0, se uso questa funzione genera un'eccezione PInvokeStackImbalance.

Come posso importare il .NET 3.5 msvcrt.dll o correggere questa eccezione?

È stato utile?

Soluzione

Ho il sospetto che il problema è con la convenzione di chiamata, si dovrebbe utilizzare cdecl.

[DllImport("msvcrt.dll", CallingConvention=CallingConvention.Cdecl)]
private unsafe static extern int strlen(byte* pByte);

Altri suggerimenti

Questo non è davvero una risposta diretta, ma sembra che per qualcosa di simile funzionalità, potrebbe essere migliore per scrivere il proprio. Ad esempio, il seguente # codice di lavoro potrebbe C (anche se ci sono probabilmente uno liners che utilizzano le funzioni esistenti che avrebbero funzionato troppo):

  static int mystrlen( byte[] pbyte )
     {
     int i = 0;
     while ( pbyte[i] != 0 )
        i++;
     return i;
     }

Non ci dovrebbe essere alcuna modifica in questo da .NET 3.5 a 4. (e, a proposito, msvcrt.dll non è parte del quadro - è il Microsft C ++ Runtime Library). Sei sicuro niente altro è cambiato nel progetto.

Ho appena provato questo codice, che funziona e stampe "4" come previsto:

class Test
{
    public unsafe static void Main(string[] args)
    {
        byte[] bytes = new byte[] {70, 40, 30, 51, 0};
        fixed(byte* ptr = bytes)
        {
            int len = strlen(ptr);
            Console.WriteLine(len);
        }
    }
    [DllImport("msvcrt.dll")]
    private unsafe static extern int strlen(byte* pByte);       
}

Non è chiaro il motivo per cui per me si sarebbe mai desidera chiamare strlen da codice gestito, ma naturalmente si potrebbe avere le tue ragioni. Se avete bisogno di un'implementazione alternativa gestita, ecco un uno di linea è possibile utilizzare:

private static int managed_strlen(byte[] bytes)
{
    return bytes.TakeWhile(b => b != 0).Count();
}

Certo che non si occupa di caratteri multi-byte (Unicode), ma non credo che lo fa strlen sia.

Solo per divertimento:

public static unsafe int strlen(void* buffer)
{
    byte* end = (byte*)buffer;
    while (*end++ != 0);
    return(int)end - (int)buffer - 1;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top