i can't test it now, but you must use Marshal.ReadInt64() because of 64bit value. and it is only one-dimensional array, so you should use freememory(result) only once at the end.
We are migrating towards a new forum system located at community.teamspeak.com, as such this forum will become read-only on January 29, 2020
i can't test it now, but you must use Marshal.ReadInt64() because of 64bit value. and it is only one-dimensional array, so you should use freememory(result) only once at the end.
I'll try, but I can't really use the readInt64 in this case because of it should be unsigned, and just casting the Pointer on ulong works fine.
It works if I release the IntPtr TS gave me instead of the offsetted ones I created btw.
Last edited by addilind; October 5th, 2010 at 04:34 PM.
all 8 bytes are stored in the return value, you can cast it to ulong and get unsigned value without any convertions. "ulong r = (ulong)Marshal.ReadInt64()". the next problem is you should not cast your 32bit value to ushort(16bit) and then to ulong(64bit), just use my command for direct write in ulong.
if your code crashes, please tell me at what command it happends. i have no 64bit system now and can't test it.
of course it works without freememory, but every using of your code will allocate memory and not release it. after some time of work your plugin will eat more and more memory.
Last edited by SpiritOffice; October 5th, 2010 at 01:40 PM.
I would like to help. and a diagram of how I can use this plugin with an external exe?
Im use vb.net
I thought I edited my post, but somehow my changes went lost:
1. It's just a typo, it should be ulong instead of ushort, but it should work without readInt64, or?
2. It works when the pointer given to me by TS3 is released instead of the offsetted ones I generated.
@ spinter: If you want to access TS3 Data in an external Program, take a look at the IPC-Plugin (sticky thread)
If you want to write a plugin in .Net, use C# or find a way to use this in VB.Net yourself, I can't help you there.
i don't want to force you to do something. if you mean that int32 is better than ulong(as it wanted by ts3 developers), than use int32.
of couse you don't need to call freememory on every offset in one-dimensional array.
is something wrong in my getCaptureModeList function?
Does anyone have an idea why the TeamSpeak3 Client crashes while using the C# Test Plugin on the TeamSpeak Plublic server? Perhaps because there is the server version 30? Sometimes it crashes after 5 sec. and sometimes after a few minutes :/ I would really like to know what the problem is, but unfortunately we cant even look in the Crash .dmp file :/
@spirit Office:Where do I use int 32? To read out the value, I just use ulong var = (ulong)Pointer for each offset, or does .Net read out only the first 4 byte? Unfortunately haven't found a server with an Channel-ID higher than 4294967295 (Range of Int) / 8589934590 (Range of Ulong), maybe I'll cheat in my TS3-Server Database to test it. But your solution should be loosing the unsigned part of the Number (9 000 000 000 000 000 000 [=2^64/2 =>signed] instead of 18 000 000 000 000 000 000[=2^64]) as you don't use an UIntPtr, or am I wrong?if you mean that int32 is better than ulong
IntPtr ptr = Marshal.AllocHGlobal(10);
Marshal.Copy(new byte[] { 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe }, 0, ptr, 8);
//unsigned 18374403900871474942
//signed -72340172838076674
ulong q = (ulong)Marshal.ReadInt64(ptr);
//q = 18374403900871474942 => FE FE FE FE FE FE FE FE
ulong w = (ulong)Marshal.ReadIntPtr(ptr);
//w = 18446744073692708606 => FF FF FF FF FE FE FE FE
int s = Marshal.SizeOf(typeof(IntPtr));
//s = 4 (32 bit system)
Sorry,for you source file is possible download all project?
Last edited by spinter; October 10th, 2010 at 08:46 PM.
Registered just to say thank you for this. I have been pulling my hair out for about 3 weeks trying to figure out how to use the some of the callbacks properly. Thanks to you I can now finish the 20 or so lines for my plugin.
the next evolution of this project may be a comilled dll, that can reference another dotnet plugin to support every language of dotnet. i think it will also be possible to debug such plugins, because they don't have to be patched for nativ using.
Last edited by SpiritOffice; October 14th, 2010 at 09:51 AM.
Ok so i must be missing something...
I'm more used to working with my own systems so, how do I go about doing this? I cant seem to get past loading the plugin. Says that the Name Version ApiVersion and such functions are not present...
Confused I am.
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
TS3Functions.csCode:public delegate void getPluginPath (string path, IntPtr maxLen);
Took a peek in the example source (plugin.c) that came with the TS3 plugin SDK download...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); }
Seems to me the wrong parameter of the two was defined as the pointer.Code:#define PATH_BUFSIZE 512 char pluginPath[PATH_BUFSIZE]; ts3Functions.getPluginPath(pluginPath, PATH_BUFSIZE);
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
TS3Functions.csCode:public delegate void getPluginPath (IntPtr path, int maxLen);
And now it works just fine (without needing an unsafe context also) using something along these lines: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); }
This goes for getAppPath, getResourcesPath and getConfigPath as well.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);
With the most recent release (rc1) and the API version change this is no longer working for me. The following logic (working previously) just returns 0.
Looking through the sdk sample I could not find anything that appears to have changed with this. Anyone have any ideas?Code:IntPtr result = IntPtr.Zero; if (TS3FunctionsDirect.getClientVariableAsString(serverConnectionHandlerID, clientID, flag, ref result) != (uint)Errors.ERROR_ok) { throw new Exception("TS3Functions.getClientVariableAsString returned an error"); } Console.WriteLine(result); // Only outputs '0' instead of the pointer as it did previously
There are currently 1 users browsing this thread. (0 members and 1 guests)