Sign in to follow this  
Followers 0
Beamer145

DllCall to function returning pointer to internal string

10 posts in this topic

Hi,

Is there a way to retrieve a string from a dll function when it is returned as a pointer to an internal zero terminated string (the pointer points to an internal static char array of the dll, I don't know up front how big the string will be).

Function prototype:

DllExport char* GetLastBoarderror(void);

I tried

$l_nResult = DllCall( $m_handleDll, "str:cdecl", "GetLastBoarderror")

If ( $DLLCALL_ERROR_OK <> @error ) Then

TI_LOG( $LOG_ERROR, $__FUNCTION__ & ": DllCall (GetLastBoarderror) failed : " & @error )

else

TI_LOG( $LOG_ERROR, $__FUNCTION__ & ": operation failed : " & $l_nResult[0] )

endif

or "str*:cdecl",

but both just give me

xxx :operation failed : {DC4}

I am pretty sure DC4 is not the string I am looking for , so it probably is the address.

I could not find a similar case on the forums, maybe I can manually read each byte with _MemoryRead but I am hoping there is a simpler way ...

Share this post


Link to post
Share on other sites



It is a proprietary dll to talk with an external board over USB, so the dll on itself is not very useful.

But the function would be the equivalent of eg:

static char l_aBuffer[MAX_ERRORSTRING_SIZE] = "";

DllExport char* GetLastBoarderror( void )

{

return l_aBuffer;

}

DllExport int doSomeStuffThatCanGoWrong( void )

{

// Oops, something went wrong

snprintf(l_aBuffer , sizeof(l_aBuffer), "Because Bill said so" );

return SOME_EPIC_FAILURE;

}

Share this post


Link to post
Share on other sites

It is a proprietary dll to talk with an external board over USB, so the dll on itself is not very useful.

Well, usually when people write dlls, it exepts like a buffer or something, so you can sent it a structure and it writes whetever to it.

Do you know how the dll is suppose to tell you what it returns and accepts for that specific function?

maybe it would except a structure or something..

$size = 100
$Struc = DllStructCreate("char["&$size&"]")
$pStruc = DllStructGetPtr($Struc)

DllCall("ur_dll", "return_type", "the_function_in_dll", "ptr", $pStruc)

$Return = DllStructGetData($Struc)

ConsoleWrite($Return & @CR)

Share this post


Link to post
Share on other sites

In the func he showed it takes no params (void) in or out.

lol I know, but iduno how they expect anyone to know how to do this without somekind of background on the dll he's using.

Share this post


Link to post
Share on other sites

lol I know, but iduno how they expect anyone to know how to do this without somekind of background on the dll he's using.

What more info would you require ?

Suppose the dll is compiled with the exact source code I gave above, so no speculation is needed on how the dll functions might work.

The function just returns a pointer to the string, it does not do anything else.

Now, how can one get to the string itself from within autoit ?

Eg if I wanted to print the string from C code using this code, I would do:

l_nResult = doSomeStuffThatCanGoWrong( );

if ( SUCCESS != l_nResult )

{

printf("A problem was detected: [%d] %s", l_nResult, GetLastBoarderror() );

}

I am looking for a similar way in autoit to convert a pointer to a string to something autoit can work with( if such functionality exists... ).

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

So why not post your autoit code exactly how you have it, and in full.

Because it is several thousand lines of code that is totally irrelevant for this issue.

Where does $DLLCALL_ERROR_OK come from for instance?

These are the error codes that DllCall may return, but wrapped in a named constant (instead of hard coded values).

If you want an equivalent autoit program of what I am trying to do it would look like.

Local Const $e_RETURNVALUE_Success = 0

Local Const $e_RETURNVALUE_Failure = 1

Local Const $LOG_ERROR = 1

Local Const $DLLCALL_ERROR_OK = 0

Local Const $DLLCALL_ERROR_UNABLETOUSE = 1

Local Const $DLLCALL_ERROR_UNKNOWNRETURNTYPE = 2

Local Const $DLLCALL_ERROR_FUNCNOTFOUND = 3

Local Const $DLLCALL_ERROR_BADNBPARAMS = 4

Local Const $DLLCALL_ERROR_BADPARAM = 5

Local Const $DEMODLL_SUCCESS = 0

Local Const $DEMODLL_SOME_EPIC_FAILURE = 1

Local $m_handleDll = -1

;...

Func Demo( )

Local $__FUNCTION__ = "Demo"

$m_handleDll = DllOpen("Demo.dll")

If ( -1 = $m_handleDll ) Then

LOG( $LOG_ERROR, $__FUNCTION__ &amp; ": DllOpen failed: Demo.dll" )

$l_nResult = $e_RETURNVALUE_Failure

EndIf

if ( $e_RETURNVALUE_Success = $l_nResult ) Then

$l_nResult = DllCall( $m_handleDll, "int:cdecl", "doSomeStuffThatCanGoWrong" )

If ( $DLLCALL_ERROR_OK <> @error ) Then

LOG( $LOG_ERROR, $__FUNCTION__ &amp; ": DllCall (doSomeStuffThatCanGoWrong) failed : " &amp; @error )

$l_nResult = $e_RETURNVALUE_Failure

elseif ( $DEMODLL_SUCCESS <> $l_nResult[0] ) Then

LOG( $LOG_ERROR, $__FUNCTION__ &amp; ": doSomeStuffThatCanGoWrong failed : " &amp; $l_nResult[0] )

; This wont work, but how to do it correclty ?

$l_nResult = DllCall( $m_handleDll, "str:cdecl", "GetLastBoarderror")

If ( $DLLCALL_ERROR_OK <> @error ) Then

LOG( $LOG_ERROR, $__FUNCTION__ &amp; ": DllCall (GetLastBoarderror) failed : " &amp; @error )

else

; This wont work, but how to do it correclty ?

LOG( $LOG_ERROR, $__FUNCTION__ &amp; ": Reason operation failed : " &amp; $l_nResult[0] )

endif

$l_nResult = $e_RETURNVALUE_Failure

Else

$l_nResult = $e_RETURNVALUE_Success

EndIf

Endif

return $l_nResult

EndFunc

Edited by Beamer145

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