Search code examples
c#teamspeak

TeamSpeak3 Client SDK -- defaultChannelArray argument for ts3client_startConnection()


I am trying to connect to my TeamSpeak3 server using a different channel from the default.

The docs say:

-defaultChannelArray

String array defining the path to a channel on the TeamSpeak 3 server. If the channel exists and the user has sufficient rights and supplies the correct password if required, the channel will be joined on login.

To define the path to a subchannel of arbitrary level, create an array of channel names detailing the position of the default channel (e.g. "grandparent", "parent", "mydefault", ""). The array is terminated with a empty string.

Pass NULL to join the servers default channel.

Here is the function signature:

unsigned int ts3client_startConnection(uint64 serverConnectionHandlerID,     
                                       const char* identity,     
                                       const char* ip,   
                                       unsigned int port,    
                                       const char* nickname,     
                                       const char** defaultChannelArray,     
                                       const char* defaultChannelPassword,   
                                       const char* serverPassword);  

TeamSpeak's C# example, which works fine, uses the method as such:

string defaultarray = "";
/* Connect to server on localhost:9987 with nickname "client", no default channel, no default channel password and server password "secret" */
error = ts3client.ts3client_startConnection(scHandlerID, identity, "localhost", 9987, "client", ref defaultarray, "", "secret");
if (error != public_errors.ERROR_ok) {
    Console.WriteLine("Error connecting to server: 0x{0:X4}", error);
    Console.ReadLine();
    return;
}

When importing the DLL in their code, they use this:

[DllImport("ts3client_win32.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "ts3client_startConnection", CharSet = CharSet.Ansi)]
public static extern uint ts3client_startConnection(uint64 arg0, string identity, string ip, uint port, string nick, ref string defaultchannelarray, string defaultchannelpassword, string serverpassword);

Now to my question: Using C#, I am trying to pass the non-default channel array to the method but it is not working so well.

I tried the following methods but to no avail:

string defaultarray = """name"", """"";
string defaultarray = "name,";

I always get an error when doing anything other than:

string defaultarray = "";

An unhandled exception of type 'System.AccessViolationException' occurred in ts3_client_minimal_sample.exe

Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

How do I get a string array from C# to a C++ DLL, all the while not using a String[]?

Thanks!


Solution

  • Thank you, Phoenix!

    The original answer didn't help but an answer further down did: esskar's answer

    Updated code:

    [DllImport("ts3client_win32.dll", CallingConvention =   CallingConvention.Cdecl, EntryPoint = "ts3client_startConnection", CharSet = CharSet.Ansi)]
    public static extern uint ts3client_startConnection(uint64 arg0, string identity, string ip, uint port, string nick, string[] defaultchannelarray, string defaultchannelpassword, string serverpassword);
    ...
    string[] defaultarray = new string[] { "name", ""};
    /* Connect to server on localhost:9987 with nickname "client", no default channel, no default channel password and server password "secret" */
    error = ts3client.ts3client_startConnection(scHandlerID, identity, "localhost", 9987, "client", defaultarray, "password", "secret");
    if (error != public_errors.ERROR_ok) {
        Console.WriteLine("Error connecting to server: 0x{0:X4}", error);
        Console.ReadLine();
        return;
    }
    

    Basically, I changed the DllImport to string[] defaultChannelArray from ref string defaultChannelArray. As another commenter on that thread mentioned, C# arrays are passed as references. Then I passed a simple C# string array. Works perfect!

    I made it more complicated than it needed to be.