Sign in to follow this  
Followers 0
brokenfox

ReturnType of structure for DLLCall

11 posts in this topic

I'm calling a DLL that returns a Structure type. I can't figure out how to get this return type from the DLLCall function. I tried ptr thinking maybe I would just a ptr to the structure but that didn't work either.

Any help is appreciated.

Share this post


Link to post
Share on other sites



Check out the

DllStructGetData ( Struct, Element [, index ] )
function

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Check out the

DllStructGetData ( Struct, Element [, index ] )
function

I'm not sure I understand. Here's the code I was using to try and reference the structure from the ptr.

$inv ="ushort id;byte Index;uint count;uint Flag;uint Price;ushort extra"
$t = DllStructCreate($inv)
for $idx=1 to 2
    $t = dllcall($dll,"ptr:cdecl","GetItem","int",$face[0],"int",$idx)
    if not @error Then
        _DebugPrint("Loop index: " & $idx & _
                    "ID: " & DllStructGetData($t,"id")& _
                    "Index: " & DllStructGetData($t,"Index")& _
                    "count: " & DllStructGetData($t,"count")& _
                    "Flag: " & DllStructGetData($t,"Flag")& _
                    "Price: " & DllStructGetData($t,"Price")& _
                    "extra: " & DllStructGetData($t,"extra"))
    end if
next

and for reference here is the function prototype:

ITEMTYPE GetItem(void* Inst,  int Index)

and structure:

Public Structure ITEMTYPE
    Dim ID As UInt16
    Dim Index As Byte
    Dim Count As UInt32
    Dim Flag As UInt32
    Dim Price As UInt32
    Dim Extra As UInt16
End Structure
Edited by brokenfox

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

$t = dllcall($dll,"ptr:cdecl","GetItem","int",$face[0],"int",$idx)

Looks like here it doesnt work.

Try those instead:

$t = dllcall($dll,"int","GetItem","int",$face[0],"int",$idx)

$t = dllcall($dll,"int:cdecl","GetItem","int",$face[0],"int",$idx)

EDIT@

You can put DllStructGetSize(Struct) to check if the Struct has data

Edited by Juvigy

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

Yeah... whatever you're trying to use... find something else. Return types cannot be structures because the only code that ever returns a structure by value is amateur code written by somebody who doesn't know what they are doing. That function is a major performance bottleneck in whatever library you're trying to use. Best of all it doesn't even align on a proper boundary due to it's size so it's wasting even more time and effort copying 24 unused bits. Honestly, either contact the author and tell them to learn how to program or find something else that is written by someone who is a bit more competent.

AutoIt does not and should not support return structures because any library worth using is going to be written properly to return either pointers or take output pointers as parameters.

Edited by Valik
Typos suck.

Share this post


Link to post
Share on other sites

If you really have to use a structure as returntype, the structure is allocated by the called function.

Then the inly thing you have to do is wrapping this memory block in an AutoIt-DLLStruct:

$aRet = DLLCall(...)
$tStruct = DLLStructCreate($tagStruct, $aRet[0])

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites

ProgAndy, it's being returned by value, not by pointer. AutoIt will truncate what is returned.

Share this post


Link to post
Share on other sites

Sorry. I missed this particular line with the function definition.


*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites

So, if it is going to truncate the returned value, then could I have it return char[x] sufficiently long enough to hold the data structure and then use DLLStructGetData with pointer to the returned char to get the data?

Also tried using dllcall($dll,"ushort;byte;uint;uint;uint;ushort:cdecl",....) but that didn't work.

Might have to scrap this and move back to VB.net as there is example code written for that but don't want to. Otherwise might have to find a different solution.

Share this post


Link to post
Share on other sites

Where did this DLL come from? Got a link to its usage docs?

You're either ignoring, or didn't understand, what Valik told you, and that makes me wonder if the DLL really behaves as you described.

:mellow:


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

PsaltyDS, I expect the DLL does behave exactly as described. I can totally see a VB .NET programmer not understanding that returning by value is a performance problem I can totally see them not understanding that returning by-value means the structure has to maintain binary compatibility for all time or the caller will break if the structure is ever changed (unless the program is re-compiled against an identical version of the structure).

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