Распределение связанного списка - PullRequest
1 голос
/ 04 июня 2009

Извиняюсь за повторное размещение.

Привет

У меня проблемы с маршалингом связанного списка из DLL.

------ C ++ Структура и функции --------

struct localeInfo { 
   WCHAR countryName[BUFFER_SIZE];
   WCHAR localeName[BUFFER_SIZE]; 
   localeInfo *next; 
}

int GetSystemLocales(localeInfo **ppList);

----------- C # Объявления -----------

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 
private struct LocaleInfo { 
   public string countryName; 
   public string localeName; 
   public IntPtr next; 
};

[DllImport("systemLocales.dll")]
private static extern int GetSystemLocales(ref IntPtr ppList);


int main() 
{ 
   var pListHead = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr))); 
   try 
   { 
       GetSystemLocales(ref pListHead); 
       var deref1(IntPtr)Marshal.PtrToStructure(pListHead, typeof(IntPtr)); 
       var deref2 = (LocaleInfo)Marshal.PtrToStructure(deref1, typeof(LocaleInfo)); 
   } 
   finally 
   { 
      Marshal.FreeHGlobal(pListHead); 
   }

}

При объявлении deref2 я получаю исключение FatalExecutionEngine. Я не могу понять, как вернуть связанный список и получить доступ к его содержимому.

Вот код C ++, который я написал, чтобы получить связанный список. Я хочу что-то подобное, чтобы работать в C #.

localeInfo *pHead = NULL; 
localeInfo *pTemp; 
GetSystemLocales(&pHead);

for(pTemp = pHead; pTemp!=NULL; pTemp = pTemp->next)
{
        wprintf(L"Display Name : %s (%s) \n", pTemp->countryName, pTemp->localeName);
}

Ответы [ 2 ]

1 голос
/ 05 июня 2009

Я ответил на ваш другой вопрос в том же духе. struct определение Шей является частью этого, но я также исправил Main.

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct LocaleInfo
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = BUFFER_SIZE)]
    public string countryName;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = BUFFER_SIZE)]
    public string localeName;
    public IntPtr next;
};

[DllImport("systemLocales.dll")]
private static extern int GetSystemLocales(ref IntPtr ppList);

static void Main()
{ 
    IntPtr pList = IntPtr.Zero;
    GetSystemLocales(ref pList);
    while (pList != IntPtr.Zero)
    {
        var info = (LocaleInfo)Marshal.PtrToStructure(pList, typeof(LocaleInfo));
        Console.WriteLine("Display Name : {0} ({1}) ", info.countryName, info.localeName);
        Marshal.FreeHGlobal(pList);
        pList = info.next;
    }
}

Тебе действительно нужно закрыть другой вопрос - я только по счастливой случайности заметил, что ты тоже написал этот вопрос.

1 голос
/ 04 июня 2009

попробуйте это:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct LocaleInfo { 
   [MarshalAs(UnmanagedType.ByValTStr, SizeConst = BUFFER_SIZE)]
   public string countryName; 
   [MarshalAs(UnmanagedType.ByValTStr, SizeConst = BUFFER_SIZE)]
   public string localeName; 
   public IntPtr next; 
};
...