2015-09-03 1 views
1

Я работаю на Teamspeak3 плагин написан на C# (с использованием this base), и я работаю на получение списка каналов, это то, как сделать это в C:Как вы выполняете итерацию через uint64 * с size_t, и что такое equivilent для C#?

/* Print list of all channels on this server */ 
    char* s; 
    char msg[1024]; 
    anyID myID; 
    uint64* ids; 
    size_t i; 
    unsigned int error; 

    if(ts3Functions.getChannelList(serverConnectionHandlerID, &ids) != ERROR_ok) { 
     ts3Functions.logMessage("Error getting channel list", LogLevel_ERROR, "Plugin", serverConnectionHandlerID); 
     return; 
    } 
    printf("PLUGIN: Available channels:\n"); 
    for(i=0; ids[i]; i++) { 
     /* Query channel name */ 
     if(ts3Functions.getChannelVariableAsString(serverConnectionHandlerID, ids[i], CHANNEL_NAME, &s) != ERROR_ok) { 
      ts3Functions.logMessage("Error querying channel name", LogLevel_ERROR, "Plugin", serverConnectionHandlerID); 
      return; 
     } 
     printf("PLUGIN: Channel ID = %llu, name = %s\n", (long long unsigned int)ids[i], s); 
     ts3Functions.freeMemory(s); 
    } 
    ts3Functions.freeMemory(ids); /* Release array */ 

В for(i=0; ids[i]; i++), он утверждает, что uint64* повторяется с помощью size_t.

Мне интересно, как итерация через это работает, и что является ближайшим эквивалентом в C#?

+0

Рассматривали ли вы проверить существующий вопрос, если это помогает, (. Повторно size_t эквивалент в C#) как [Правильный путь маршала size_t * ?] (http://stackoverflow.com/questions/1309509/correct-way-to-marshal-size-t) Короткий ответ: «** Используя IntPtr ** и/или ** UIntPtr ** делает это правильно - типы есть там специально для этой цели! ... » – localhost

+0

Я просмотрел этот комментарий, но я также спрашиваю, как итерация возможна с помощью size_t, и если есть способ сделать то же самое в C#. Потому что в этом примере я понятия не имею, каковы последствия этого. – Birdboat

+0

Из моего собственного тестирования, итерация над 'size_t' похожа на итерацию по' int', за исключением того, что переменная определяется как 'size_t', а не' int', а сравнение в цикле также должно выполняться с использованием переменной типа 'size_t'. Только в качестве примечания можно использовать тип-литье в int; то есть '(int) my_size_t', однако, нецелесообразно - относиться к каждому типу как к его правильному типу, когда литье не является необходимым. Для Q о том, как это сделать на C#. [C#: Извлечение и использование IntPtr * через отражение] (http://stackoverflow.com/questions/1126034/c-retrieving-and-using-an-intptr-through-reflection) help? – localhost

ответ

0

Я нашел ответ (благодаря локальному хосту и Крису, чтобы узнать это!). В основном, ulong* указывал на массив, и size_t проходил через него, пытаясь найти идентификаторы канала. Поскольку в C++ в цикле for каждое число, кроме нуля, истинно, оно продолжало запрашивать его, пока не было больше идентификаторов каналов, и был возвращен ноль. The TeamSpeak Community Forums Post

Для тех, кто заинтересован о коде в C# с помощью this plugin:

if (funcs.getChannelList(serverConnectionHandlerID, ref v) != Errors.ERROR_ok) { 
    funcs.logMessage("Failed", LogLevel.LogLevel_ERROR, "Plugin", serverConnectionHandlerID); 
    break; 
} 
// Convert it to a ulong* 
ulong * ptr = (ulong *) v.ToPointer(); 
// Iterate through the array 
for (ulong t = 0; ptr[t] != 0; t++) { 
    // The String result 
    string result; 
    // The pointer result 
    IntPtr res = IntPtr.Zero; 
    /* 
    Channel Variable Arguments: 
    1: The server connection ID 
    2: The iterated channel id 
    3: An IntPtr at 0, which signifies CHANNEL_NAME 
    4: A reference to stores results 
    */ 
    if (
    funcs.getChannelVariableAsString(serverConnectionHandlerID, ptr[t], new IntPtr(0), ref res) != Errors.ERROR_ok) { 
     // Error message 
     funcs.logMessage("Error", LogLevel.LogLevel_WARNING, "Plugin", serverConnectionHandlerID); 
     break; 
    } 
    // Convert the pointer to a string 
    if ((result = Marshal.PtrToStringAnsi(res)) == null) break; 
    // Print it 
    funcs.printMessageToCurrentTab(result); 
}