Tengo dos implementaciones diferentes para ordenar el código C en C#.
En primer lugar, el código C es:
int GetVersion(char * pVer, size_t * piSize);Mi primer intento en C# (no muestro la parte DllImport):
static extern int GetVersion( byte[] ver, ref UIntPtr size );Y el otro intento en C#:
static extern int GetVersion([MarshalAs(UnmanagedType.LPStr)] StringBuilder ver, ref ulong size);Llegué a través de estos de diferentes ejemplos en net. Pero no puedo concluir cuál es la correcta.
Huesos básicos: siempre podemos hacer esto
static extern int GetVersion(IntPtr ver, ref UIntPtr size );Nunca escribiría esto porque no me gusta lo que genera para la conversión A->W:
static extern int GetVersion([MarshalAs(UnmanagedType.LPStr)] StringBuilder ver, ref UIntPtr size);Además, si se trata de una cadena contada verdadera, el código P/Invoke no funciona porque quiere un 0 después del final.
normalmente escribiría
static extern int GetVersion( byte[] ver, ref UIntPtr size ); en el que primero debe crear ver en el tamaño máximo. Luego puede convertir ver a cadena usando las cosas en System.Text.Encoding . Es casi seguro que GetVersion() pasa una constante hacia atrás, por lo que puede codificar la codificación correcta (probablemente ASCII de todos modos).
Hay muchas posibilidades de que te estés perdiendo [DllImport(..., CallingConvention=CallingConvention.Cdecl)] , lo que te está causando daños en la memoria, pero en realidad no puedo decirlo.
Error: no use ulong para size_t . size_t es UIntPtr en todas las plataformas compatibles.
El comentario sugiere una firma completamente diferente GetDevInfo(int Index, DevInfo * pdevInfo); Esto es algo completamente diferente y claramente hay una mejor opción:
const int IDLength = 100; [StructLayout(LayoutKind.Sequential)] struct DeviceInfo { [MarshalAs(UnmanagedType.ByValArray, SizeConst = IDLength)] byte[] ID; } static extern /* I don't know what's here because missing from comment */ GetDevInfo(int index, ref strcut DeviceInfo info); string GetInfo(int index) { var info = new DeviceInfo(); info.ID = new byte[IDLength]; GetDevInfo(info.ID); return System.Text.Encoding.ASCII.GetString(info.ID, 0, strlen(info.ID)); } int strlen(byte[] bytes) { int i; for (i = 0; i < bytes.Length && bytes[i] != 0; i++) ; return i; } ````