Jump to content

DllCall and Struct and Tsremote.dll - what's wrong


Recommended Posts

I've been trying to use the tsremote dll to control my teamspeak client based on text commands.

Anyhow, I found some documentation on how to call the functions and was trying to translate them into autoit.

For the most part, they're working ok, but I've reached my wits end trying to figure out why one thing will not work:

original:

PtsrChannelInfo = ^TtsrChannelInfo; 
TtsrChannelInfo = packed record 
ChannelID : Integer; 
ChannelParentID : Integer; 
PlayerCountInChannel : Integer; 
ChannelFlags : Integer; 
Codec : Integer; 
Name : Array [0..29] of Char; 
end; 

Procedure DoGetChannels; 
var 
ChannelsInfo : Array[0..1023] of TtsrChannelInfo; 
Records : Integer; 
I: integer; 
begin 
Records := 1024; 
if not DisplayResult( tsrGetChannels(@ChannelsInfo, @records) ) then exit; 
Writeln('ChannelCount: ',Records); 
if Records > 0 then 
for I :=0 to Records-1 do DisplayChannelInfo(ChannelsInfo[I]); 
end;

autoit attempt:

Global Const $type_tsrChannelInfo = "int;int;int;int;int;char[30]"

Dim $Channels[8][6]
DoGetChannels( $Channels);

Func DoGetChannels( $Channels );
  Dim $Channel, $ChannelArray[6]

  $struct=""
  For $i = 1 to UBound( $Channels)
    $struct &= $type_tsrChannelInfo & ";"
  Next

  $ChannelsInfo = DllStructCreate( $struct )
  $Records = DllStructCreate( "int" )
  DllStructSet( $Records, 1, Ubound( $Channels) )
    
  $Result = DllCall( $TSRemote, "INT", "tsrGetChannels", "PTR", DllStructPtr( $ChannelsInfo ), "PTR", DllStructPtr( $Records) )
    
  if @error <> 1 Then
         
    If DllStructGet( $Records, 1) > 0 Then
             
      For $j = 0 to Ubound( $Channels ) -1
        For $i = 1 to 6
          $ChannelArray[ $i-1 ] = DllStructGet( $ChannelsInfo, $i + ( $j*6) )
          $Channels[$j][ $i-1 ] = DllStructGet( $ChannelsInfo, $i + ( $j*6) )
        Next
             
        $Channel = DisplayChannelInfo( $ChannelArray )
             
        MsgBox( 0, "Channel Info", $Channel )
      Next
    EndIf
  EndIf
     
  DllStructFree( $ChannelsInfo )
EndFunc

Anyhow, the above code works fine up to

Dim Channels[8][6]

but if I try to for to [9][6] or gasp, [1024][6] the script dies with a windows "We apologize for the inconvenience but autoit needs to close". It's dying on the DllCall, but I have no idea why. Any help would be greatly appreciated, and I can provide more information if you specify what would be useful.

Editted to include the correct function in the origional code... OOPS

Edited by mother9987
Link to comment
Share on other sites

Took some thinking but I know why, helps that I wrote DllStructCreate :( Your string that you are passing to DllStructCreate is too big, it's over 255 characters long. I bet if you check @error after DllStructCreate you will see it's been set.

For right now you could try(untested):

Global Const $type_tsrChannelInfo = "int;int;int;int;int;char[30]"

Dim $Channels[1024][6]
$iNumChannels = DoGetChannels( $Channels);

Func DoGetChannels( ByRef $Channels );
  Local $Channel, $ChannelArray[6],$iNumChannels=0,$i,$j,$Result,$Records,$ChannelsInfo

  $ChannelsInfo = DllStructCreate( "byte[51200]" )
  If @error Then return -1
  $Records      = DllStructCreate( "int" )
    
  $Result = DllCall( $TSRemote, "INT", "tsrGetChannels", "PTR", DllStructPtr( $ChannelsInfo ), "PTR", DllStructPtr( $Records) )
    
  if Not @error Then
      $iNumChannels = DllStructGet($Records,1)
    For $j = 0 To $iNumChannels-1
        $p  = DllStructCreate("int;int;int;int;int;char[30]",DllStructPtr($ChannelsInfo) + (50 * j))

        For $i = 1 To 6
            $ChannelArray[ $i-1 ] = DllStructGet( $p, $i)
            $Channels[$j][ $i-1 ] = $ChannelArray[$i-1]
        Next
        
        $Channel = DisplayChannelInfo( $ChannelArray )
            
        MsgBox( 0, "Channel Info", $Channel )
    Next
  EndIf
    
  DllStructFree( $ChannelsInfo )
  DllStructFree($Records)

  Return $iNumChannels
EndFunc

*EDIT

I'll go back and make your original code work with DllStructCreate(), I never thought someone would make a string 29696 characters long to pass to DllStructCreate() :(

Edited by Ejoc
Start -> Programs -> AutoIt v3 -> AutoIt Help File -> Index -> (The Function you are asking about)----- Links -----DllStruct UDFsRSA Crypto UDFs
Link to comment
Share on other sites

It might be worth making a note of the maximum string length in the Remarks section in the Docs.  Just a thought.

<{POST_SNAPBACK}>

Removed the string limit :(
Start -> Programs -> AutoIt v3 -> AutoIt Help File -> Index -> (The Function you are asking about)----- Links -----DllStruct UDFsRSA Crypto UDFs
Link to comment
Share on other sites

You, sir, are a god, and an example to the masses, thanks for so quickly finding the problem.

But, I did check @error and it was 0... I cut out most of the checks that I had added to the code for brevity - but they are there :(

Edited by mother9987
Link to comment
Share on other sites

Interesting, when I worked on your code I was getting an error message, anyway beta 3.1.1.23 removed the string limit, so give it a try.

Edited by Ejoc
Start -> Programs -> AutoIt v3 -> AutoIt Help File -> Index -> (The Function you are asking about)----- Links -----DllStruct UDFsRSA Crypto UDFs
Link to comment
Share on other sites

Ok, that function is now working. But, I have a new problem in another function. I'm probably just confused - and will never figure this one out on my own:

Original:

PtsrPlayerInfo = ^TtsrPlayerInfo; 
TtsrPlayerInfo = packed record 
PlayerID : Integer; 
ChannelID : Integer; 
NickName : Array [0..29] of Char; 
PlayerChannelPrivileges : Integer; 
PlayerPrivileges : Integer; 
PlayerFlags : Integer; 
end; 

PtsrChannelInfo = ^TtsrChannelInfo; 
TtsrChannelInfo = packed record 
ChannelID : Integer; 
ChannelParentID : Integer; 
PlayerCountInChannel : Integer; 
ChannelFlags : Integer; 
Codec : Integer; 
Name : Array [0..29] of Char; 
end; 

PtsrUserInfo = ^TtsrUserInfo; 
TtsrUserInfo = packed record 
Player : TtsrPlayerInfo; 
Channel : TtsrChannelInfo; 
ParentChannel : TtsrChannelInfo; 
end; 

procedure DoGetUserInfo; 
var 
UserInfo: TtsrUserInfo; 
begin 
if not DisplayResult( tsrGetUserInfo(@UserInfo) ) then exit; 
Writeln('User: '); 
DisplayDetailedPlayerInfo(UserInfo.Player); 
Writeln('Channel: '); 
DisplayChannelInfo(Userinfo.Channel); 
if UserInfo.Channel.ChannelParentID -1 then 
begin 
Writeln('Parent Channel: '); 
DisplayChannelInfo(Userinfo.ParentChannel); 
end; 
end;

The nested structs are giving me problems.

I tried making a struct of just...

Global Const $type_tsrPlayerInfo = "int;int;char[30];int;int;int"
Global Const $type_tsrChannelInfo = "int;int;int;int;int;char[30]"
Global Const $type_tsrUserInfo = $type_tsrPlayerInfo & $type_tsrChannelInfo & $type_tsrChannelInfo

$UserInfo = DllStructCreate( $type_tsrUserInfo )
$Result = DllCall( $TSRemote, "INT", "tsrGetUserInfo", "PTR", DllStructGetPtr( $UserInfo ) )

and...

$PlayerInfo = DllStructCreate( $type_tsrPlayerInfo )
$ChannelInfo = DllStructCreate( $type_tsrChannelInfo )
$ParentChannelInfo = DllStructCreate( $type_tsrChannelInfo )
    
$UserInfo = DllStructCreate( "ptr;ptr;ptr" )
if @error then Return -1
        
DllStructSetData( $UserInfo, 1, DllStructGetPtr( $PlayerInfo ) )
DllStructSetData( $UserInfo, 2, DllStructGetPtr( $ChannelInfo ) )
DllStructSetData( $UserInfo, 3, DllStructGetPtr( $ParentChannelInfo ) )
        
$Result = DllCall( $TSRemote, "INT", "tsrGetUserInfo", "PTR", DllStructGetPtr( $UserInfo ) )

But I've come to the conclusion that I really don't know what I'm doing. I get a this program needs to close error on the DllCall again.

I've looked at the rest of the functions, and if I can get this one working, the rest will be cake and I won't need to bother you all again :( So, thanks in advance for any help!

Link to comment
Share on other sites

Global Const $type_tsrUserInfo = $type_tsrPlayerInfo & $type_tsrChannelInfo & $type_tsrChannelInfo

try:

Global Const $type_tsrUserInfo = $type_tsrPlayerInfo & ";" & $type_tsrChannelInfo & ";" & $type_tsrChannelInfo

Start -> Programs -> AutoIt v3 -> AutoIt Help File -> Index -> (The Function you are asking about)----- Links -----DllStruct UDFsRSA Crypto UDFs
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...