Couldn't figure out the getPluginPath function assuming it had been implemented correctly in the C# version.
Then I considered it may not be and took a closer look.
This is what it looked like:
TS3FunctionsCallback.cs
Code:
public delegate void getPluginPath (string path, IntPtr maxLen);
TS3Functions.cs
Code:
public static void getPluginPath(string path, IntPtr maxLen)
{
//if (TS3FunctionsDirect.getCurrentServerConnectionHandlerID() != (uint)Errors.ERROR_ok)
//{
// throw new Exception("TS3Functions.getCurrentServerConnectionHandlerID returned an error");
//}
TS3FunctionsDirect.getPluginPath(path, maxLen);
}
Took a peek in the example source (plugin.c) that came with the TS3 plugin SDK download...
Code:
#define PATH_BUFSIZE 512
char pluginPath[PATH_BUFSIZE];
ts3Functions.getPluginPath(pluginPath, PATH_BUFSIZE);
Seems to me the wrong parameter of the two was defined as the pointer.
Clearly the second parameter should be the number indicating buffer size itself and the first one is a pointer since strictly speaking at low level strings are always passed by pointer since arguments are pushed onto the stack typically as processor native sized integers (32 or 64 bit) prior to executing a CALL and changing stack frame.
Feel free to point out to me if using these functions as is was in fact possible using C#'s terribly vague high-level approaches in some way, but I seem to have missed something if that's the case.
Thus I made the following changes:
TS3FunctionsCallback.cs
Code:
public delegate void getPluginPath (IntPtr path, int maxLen);
TS3Functions.cs
Code:
public static void getPluginPath(IntPtr path, int maxLen)
{
//if (TS3FunctionsDirect.getCurrentServerConnectionHandlerID() != (uint)Errors.ERROR_ok)
//{
// throw new Exception("TS3Functions.getCurrentServerConnectionHandlerID returned an error");
//}
TS3FunctionsDirect.getPluginPath(path, maxLen);
}
And now it works just fine (without needing an unsafe context also) using something along these lines:
Code:
using System.Runtime.InteropServices;
const int PathBufferSize = 512;
IntPtr ptr = Marshal.AllocHGlobal(PathBufferSize);
TS3Functions.getPluginPath(ptr, PathBufferSize);
string PluginPath = Marshal.PtrToStringAnsi(ptr);
Marshal.FreeHGlobal(ptr);
This goes for getAppPath, getResourcesPath and getConfigPath as well.