Jump to content
Sign in to follow this  
Suirad

working with a custom dll

Recommended Posts

Suirad

im having an issue passing strings to/from my dll that i am making. should i pass it as a pointer? i really have no idea of what the problem is but every time i try testing it the autoit script crashes :\

Share this post


Link to post
Share on other sites
monoceres

How else should you pass it?

Some code might help..


Broken link? PM me and I'll send you the file!

Share this post


Link to post
Share on other sites
Richard Robertson

Strings come in two flavors, which string are you using?

Share this post


Link to post
Share on other sites
Inverted

Just use type "str" , works fine.

Also, make sure you remember register preservation so as not to screw autoit's code after returning.

Better show some code.

Edited by Inverted

Share this post


Link to post
Share on other sites
Suirad

my autoit code:

$num = dllcall("dll2.dll","str","Test@4","str","crap")
if @error > 0 then
    MsgBox(0,"Error Code:",@error)
    Exit
EndIf
ConsoleWrite($num[0]&@CRLF)

My FreeBasic dll code:

function Test alias "Test" (tstr As string Ptr) As string Export
    Dim lol As String
    lol = *tstr
    lol = "My name is Test. You said: "+lol
    return lol
End Function

the dll compiles fine with no error. but when i try running this with autoit it crashes.

this is my first time working with strings and dlls. i have no problem working with integers, but im trying to move onto strings

Edited by Suirad

Share this post


Link to post
Share on other sites
monoceres

I helped SmOke_N with the exact same issue some time ago. The trick is that your freebasic ges oput of scope when your function returns so freebasic clears up the memory, thus you try to access unallocated memory in autoit.

Try decalring the freebasic string as shared and everything will work.


Broken link? PM me and I'll send you the file!

Share this post


Link to post
Share on other sites
wraithdu

I think you may need to define 'lol' as a ZString as well and give it a finite length. I forget exactly, haven't used FreeBasic in a while.

Share this post


Link to post
Share on other sites
Suirad

hmm i changed the dll code to:

Function Test alias "Test" (tstr As string Ptr) As string Export
    Dim As ZString Ptr lol
    lol = Allocate(50)
    *lol = *tstr
    *lol = "My name is Test. You said: "+*lol
    return *lol
End Function

and i also tried:

Dim shared As ZString Ptr lol
Function Test alias "Test" (tstr As string) As string Export
    
    lol = Allocate(50)
    *lol = tstr
    *lol = "My name is Test. You said: "+*lol
    return *lol
End Function

yet autoit still crashes with the exit code of -1073741819 if that matters.

i have a feeling that ive changed it wrong as im not too experienced with pointers

Share this post


Link to post
Share on other sites
LarryDalooza

Have you searched all the freebasic references in the forum?

In my forum search... I see a lot of CDECL in freebasic code written for autoit to use. There may be other good info too, before burning member's time researching for you.

Lar.


f_mrcleansmalm_77ce002.jpgAutoIt has helped make me wealthy

Share this post


Link to post
Share on other sites
Richard Robertson

Strings are better returned by using a passed pointer than by return value.

Share this post


Link to post
Share on other sites
Suirad

Have you searched all the freebasic references in the forum?

In my forum search... I see a lot of CDECL in freebasic code written for autoit to use. There may be other good info too, before burning member's time researching for you.

Lar.

any time i add the CDECL thing to the code it causes a crash

(tested with an already working dll that just takes/returns int's)

also im making the dll to be compatible with other languages, so im not looking into making a plugin

Strings are better returned by using a passed pointer than by return value.

could you better explain this or give an example? Edited by Suirad

Share this post


Link to post
Share on other sites
Richard Robertson

I have no idea how it works in Freebasic, but in C++ you would ask for a character pointer and a length value, then fill the character pointer you were passed, up to the length of the space allocated.

Share this post


Link to post
Share on other sites
wraithdu

You'll also want to make sure you use DllOpen() and DllClose() and that you retrieve the string / ptr before you call DllClose(). Otherwise the memory you're trying to access is freed when the dll closes, and you'll crash with an access violation of some sort.

Ideally you'll do this like Windows API calls. You should pass a pointer to your own allocated string buffer and have your dll function fill it with data.

Edited by wraithdu

Share this post


Link to post
Share on other sites
Suirad

after looking up a bit about pointers, and reading your responces, ive changed my code to

autoit:

$thedll = DllOpen("dll2.dll")
$dll = dllcall($thedll,"str","Test@4","str","crap")
if @error > 0 then
    MsgBox(0,"Error Code:",@error)
    Exit
EndIf
dllclose($thedll)
ConsoleWrite($dll[0]&@CRLF)

freebasic

Function Test alias "Test" (tstr As string) As String Export
    Dim As String Ptr lol = @tstr
    lol = Allocate(28 + (SizeOf(String) * 2))
    *lol = "My name is Test. You said: "+*lol
    Return *lol
    'DeAllocate(lol)
End Function

but its still as unsuccessful. :\

Share this post


Link to post
Share on other sites
Richard Robertson

You can't reallocate the buffer.

Try making a function that matches a signature like:

Sub Test alias "Test" (tstr as char ptr, length as integer)

and then copy your string into tstr characters up to length.

Share this post


Link to post
Share on other sites
Valik

There is no need to use DllOpen() and DllClose(). The string is copied when using the "str" parameter. It would be rather stupid if it wasn't.

Did you actually try what Larry suggested (looking up examples)? Chances are he's right and you're using the wrong calling convention. Additionally I don't see where Larry actually said to change the FreeBasic DLL's calling convention. That's a hint, by the way.

Share this post


Link to post
Share on other sites
wraithdu

I meant for him to use Open / Close if he decides to pass back a pointer to memory allocated by the dll, so the 'ptr' parameter.

Incidentally, when you are returned parameters using 'str' or 'wstr', what's the size of the AutoIt allocated string buffer? Does it start really big, then it's resized, or is it just "big enough"?

Edited by wraithdu

Share this post


Link to post
Share on other sites
monoceres

Enough!

Lets sort out the confusion here. I actually have freebasic installed so lets look how it should have been done:

FreeBasic source:

Function Test alias "Test" (indata As ZSTRING PTR,outdata As ZSTRING PTR) As INTEGER Export
    'Write the strings to the location of outdata (we assume this points to valid memory)
    'We write from a constants string plus the location of indata
    *outdata="My name is Test. You said: "+(*indata)
    'We return '0' because everything went smoothly
    return 0
End Function

AutoIt source:

; We allocate the string buffer for the dll function
$buff=DllStructCreate("char[255]")

; Notice the '@8' it's because we're using the __stdcall convention which automaticly adds @ plus the amount of bytes in the parameters
; In this case 8 because we push two pointers 4bytes+4bytes
DllCall("basic.dll","int","Test@8","str","Andreas","ptr",DllStructGetPtr($buff))

; Fetch the 'return'
MsgBox(0,"Result:"&@error,DllStructGetData($buff,1))

As you can see I used two parameters instead off one, it's much cleaner to part input from output.

Also the __stdcall convention is used by default (but can be changed to __cdecl, I would actually prefer it in this case to avoid the annoying decoration).

Also, what fuckup at the dev team for freebasic decided the ' character would be great for comments?

Edited by monoceres

Broken link? PM me and I'll send you the file!

Share this post


Link to post
Share on other sites
Valik

Incidentally, when you are returned parameters using 'str' or 'wstr', what's the size of the AutoIt allocated string buffer? Does it start really big, then it's resized, or is it just "big enough"?

It's a static size I can't recall off the top of my head. It's fairly large (64KB maybe?).

Edit: Doh, I knew it was stdcall, I saw the @4 but forgot.

Edited by Valik

Share this post


Link to post
Share on other sites
Suirad

Enough!

Lets sort out the confusion here. I actually have freebasic installed so lets look how it should have been done:

FreeBasic source:

Function Test alias "Test" (indata As ZSTRING PTR,outdata As ZSTRING PTR) As INTEGER Export
    'Write the strings to the location of outdata (we assume this points to valid memory)
    'We write from a constants string plus the location of indata
    *outdata="My name is Test. You said: "+(*indata)
    'We return '0' because everything went smoothly
    return 0
End Function

AutoIt source:

; We allocate the string buffer for the dll function
$buff=DllStructCreate("char[255]")

; Notice the '@8' it's because we're using the __stdcall convention which automaticly adds @ plus the amount of bytes in the parameters
; In this case 8 because we push two pointers 4bytes+4bytes
DllCall("basic.dll","int","Test@8","str","Andreas","ptr",DllStructGetPtr($buff))

; Fetch the 'return'
MsgBox(0,"Result:"&@error,DllStructGetData($buff,1))
Wow. Thanks a ton, it works perfectly, i understand completely now.

Also, what fuckup at the dev team for freebasic decided the ' character would be great for comments?

agreed, i always find myself hitting ; when trying to comment out things :)

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  

×