AutoHotkey Community

It is currently May 26th, 2012, 11:24 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 6 posts ] 
Author Message
 Post subject: DllCall within Function
PostPosted: May 22nd, 2005, 8:42 pm 
Offline
User avatar

Joined: December 29th, 2004, 1:28 pm
Posts: 2542
The ability to use DllCall within a function... :)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: May 23rd, 2005, 1:20 am 
Offline

Joined: March 2nd, 2004, 3:36 pm
Posts: 10720
In the body of a function? In a function call (expression)? I think both of these work, so perhaps you could give an example.

Maybe it's the help file being vague again.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: May 23rd, 2005, 3:58 am 
Offline
User avatar

Joined: December 29th, 2004, 1:28 pm
Posts: 2542
Chris wrote:
In the body of a function? In a function call (expression)? I think both of these work, so perhaps you could give an example.

Maybe it's the help file being vague again.

This seems to work ok:
Code:
; CMDret (DLL version) examples
CMD := COMSPEC " /C set"

  hModule := DllCall("LoadLibrary", "str", "cmdret.dll","UInt")
  VarSetCapacity(StrOut, 1000)
  DllCall("lstrcpyA", "str", StrOut, "int", DllCall("cmdret.dll\RunRedirect", "str", CMD))
  DllCall("FreeLibrary", "UInt", hModule)

MsgBox, %StrOut%


This doesn't (unless it's something that I'm misunderstanding). It dies asking if I'd like to send a report to M$.
Code:
; CMDret (DLL version) examples
ret1 := CMDreturn(COMSPEC " /C set")
MsgBox, %ret1%


CMDreturn(CMD)
{
  hModule := DllCall("LoadLibrary", "str", "cmdret.dll","UInt")
  VarSetCapacity(StrOut, 1000)
  DllCall("lstrcpyA", "str", StrOut, "int", DllCall("cmdret.dll\RunRedirect", "str", CMD))
  DllCall("FreeLibrary", "UInt", hModule)
  Return StrOut
}


Edit: Spelling typos


Last edited by corrupt on May 23rd, 2005, 8:31 pm, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: May 23rd, 2005, 4:03 am 
Offline
User avatar

Joined: December 29th, 2004, 1:28 pm
Posts: 2542
Seems to be this line when within a function:
Code:
DllCall("lstrcpyA", "str", StrOut, "int", DllCall("cmdret.dll\RunRedirect", "str", CMD))

Splitting the line into 2 lines (2 separate calls) still seems to fail...
Code:
  temp := DllCall("cmdret.dll\RunRedirect", "str", CMD)
  DllCall("lstrcpyA", "str", StrOut, "int", temp)
but... if either of these 2 lines are commented out the script does not crash (it doesn't work but doesn't crash).

I'm using AHK ver 1.0.33.01 & WinXP Pro SP2 btw :)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: May 24th, 2005, 1:55 am 
Offline

Joined: March 2nd, 2004, 3:36 pm
Posts: 10720
It took me a while to figure this one out because at first I was sure it was either a bug or something to do with your DLL's use of global memory (in spite of the fact that it copies its global memory to a safe area via lstrcpy before doing FreeLibrary).

But I think the solution is that you didn't give StrOut enough capacity. Try increasing it from 1000 to 5000. If it doesn't crash, use StringLen on the result. Chances are, it's bigger than 1000 (at least it is on mine).

Assuming this solves it, you might ask why it crashes only when called inside a function. It's probably because local variables use a different memory strategy than global variables -- one that might be more vulnerable to misdeeds such as buffer overflow.

By the way, if you have the DLL copy its result into a string provided by the caller, you can avoid the need for LoadLibrary(), FreeLibrary() and lstrcpy(). But from what you said before, perhaps there is a design reason you can't do this.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: May 24th, 2005, 3:22 am 
Offline
User avatar

Joined: December 29th, 2004, 1:28 pm
Posts: 2542
Chris wrote:
But I think the solution is that you didn't give StrOut enough capacity. Try increasing it from 1000 to 5000. If it doesn't crash, use StringLen on the result. Chances are, it's bigger than 1000 (at least it is on mine).

:oops: That would do the trick. Thanks.

Chris wrote:
By the way, if you have the DLL copy its result into a string provided by the caller, you can avoid the need for LoadLibrary(), FreeLibrary() and lstrcpy(). But from what you said before, perhaps there is a design reason you can't do this.
I'll look into doing this. Thanks


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: No registered users and 4 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group