1

I am working on a Teamspeak3 Plugin written in c#(using this base) and I'm working on getting a channel list, this is how to do it in 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 */

At for(i=0; ids[i]; i++), it states that a uint64* is being iterated through with a size_t.

I am wondering how iterating through that works, and what is the closest equivalent in c#?

Birdboat
  • 46
  • 7
  • Have you considered checking an existing question, if it helps, (re. size_t equivalent in C#) like [Correct way to marshal SIZE_T*?](http://stackoverflow.com/questions/1309509/correct-way-to-marshal-size-t) Short answer: "**Using IntPtr** and/or **UIntPtr** is doing it properly - the types are there specifically for this purpose!..." – localhost Sep 03 '15 at 00:07
  • I have looked at that comment, but I am also asking how is iterating possible with size_t and if there is a way to do the same in c#. Because in the example I have no idea what the effects are of doing so. – Birdboat Sep 03 '15 at 00:32
  • From my own testing, iterating over a `size_t` is similar to iterating over an `int`, except the variable is defined as `size_t` rather than an `int` and the comparison in the loop should also be done using a variable of the `size_t` type. Only as a note, type-casting to int can be done; i.e. `(int)my_size_t` however, it is not advisable--treat each type as its correct type when casting is not necessary. For Q about how to do in C#. Does [C#: Retrieving and using an IntPtr* through reflection](http://stackoverflow.com/questions/1126034/c-retrieving-and-using-an-intptr-through-reflection) help? – localhost Sep 03 '15 at 00:38
  • Sorry about inactivity, anyway, I did the equivalent of this in c++. I found that [this](http://prntscr.com/8fvpsf) returned [this](http://prntscr.com/8fvor4). Still trying to figure out why this works. – Birdboat Sep 13 '15 at 15:57

1 Answers1

0

I found the answer (thanks to localhost and Chris for finding this out!). Basically, the ulong* was pointing to an array, and the size_t was going through it, trying to find the channel's ids. Because in C++, in a for loop, every number besides zero is true, it kept querying it until there were no more channel ids, and a zero was returned. The TeamSpeak Community Forums Post

For anyone interested about the code in C# using 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);
}
Birdboat
  • 46
  • 7