Sign in to follow this  
Followers 0
mother9987

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

11 posts in this topic

#1 ·  Posted (edited)

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

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

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

Share this post


Link to post
Share on other sites

I changed DllStructCreate() your original code will work once it hits beta.


Start -> Programs -> AutoIt v3 -> AutoIt Help File -> Index -> (The Function you are asking about)----- Links -----DllStruct UDFsRSA Crypto UDFs

Share this post


Link to post
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.


601DisengageEnd Program

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

nice... :(


601DisengageEnd Program

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

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

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

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

Share this post


Link to post
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!

Share this post


Link to post
Share on other sites

#10 ·  Posted

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

Share this post


Link to post
Share on other sites

#11 ·  Posted

try:

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

<{POST_SNAPBACK}>

doh!!! thanks!

Share this post


Link to post
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
Sign in to follow this  
Followers 0