Sign in to follow this  
Followers 0
bittware

Why can't my DllCall return array variable?

9 posts in this topic

#1 ·  Posted (edited)

Hello experts,

I use following codes and want to get parameter $byte value from its return array.

$re_stat = DllCall($hDll, "int:cdecl", "sub_spi_transfer", "ptr", $hSubHandle, "char*", $byte, "char*", 0, "int", 1, "int", $SS_CONF)
$re_stat_value = $re_stat[2]

But when I run the application, AutoIt prompts me ERROR "Subscript used with non-Array variable.". Why is that?

Does not the DllCalled function return value in array form?

Thanks for any comments.

BRs,

bittware

Edited by bittware

Share this post


Link to post
Share on other sites



Hello experts,

Forgive me to ask such basic question...

What's the difference between these two variables?

Local $data_byte = 6
$re_stat = DllCall($hDll, "int:cdecl", "sub_spi_config", "ptr", $hSubHandle, "int", 0, "int*", $data_byte)
$re_stat_value = $re_stat[3]

$data_byte V.S. $re_stat_value

Should not they be with identical value? In fact, they are not. $data_byte keeps its value of 6 whereas $re_stat_value value is assigned by DllCalled function. What's the role of $data_byte here?

BRs,

bittware

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

edited: I was mistaken...

Quote from help file:

If the function call fails then @error is set to 1. Otherwise an array is returned that contains the function return value and a copy of all the parameters (including parameters that the function may have modified when passed by reference).

$return[0] = function return value

$return[1] = param1

$return[2] = param2

...

$return[n] = paramn

Parameter 3 is int* which is a pointer to an int. It's a guess but I think $data_byte value is substituted locally within autoit 1st, and when the DLL calls the function with a literal value, it must either copy it somewhere and use a pointer to it or maybe even use the number 6 as the pointer to a memory location, which would probably lead to errors or wild results. Either way $re_stat[3] would be the value used for param3 by the internal dll function, not necessarily the same value passed into the dllcall from autoit, especially if the function modifies it.

Edited by ShawnW

Share this post


Link to post
Share on other sites

It should, but I'd check for @error values anyway even though it should still be an array. Also, are you sure the error came from that line?

Share this post


Link to post
Share on other sites

It should, but I'd check for @error values anyway even though it should still be an array. Also, are you sure the error came from that line?

I just test it. It shows @error = 1 which means function call failure.

I'm sure it comes from that line...

Is it possible to let me know what kind of error has occurred?

Share this post


Link to post
Share on other sites

edited: I was mistaken...

Quote from help file:

If the function call fails then @error is set to 1. Otherwise an array is returned that contains the function return value and a copy of all the parameters (including parameters that the function may have modified when passed by reference).

$return[0] = function return value

$return[1] = param1

$return[2] = param2

...

$return[n] = paramn

Parameter 3 is int* which is a pointer to an int. It's a guess but I think $data_byte value is substituted locally within autoit 1st, and when the DLL calls the function with a literal value, it must either copy it somewhere and use a pointer to it or maybe even use the number 6 as the pointer to a memory location, which would probably lead to errors or wild results. Either way $re_stat[3] would be the value used for param3 by the internal dll function, not necessarily the same value passed into the dllcall from autoit, especially if the function modifies it.

It sounds like reasonable explanation.

This inspired me to ask another question. What's if I just pass a ByRef variable to the position of "$data_byte"? Will the DllCalled function internally change the external variable value the ByRef points to? By your explanation, it will not. DllCalled function will not take effect on any external variable value even it is passed as its reference(address or pointer). Am I right?

Share this post


Link to post
Share on other sites

Oh, I found the problem...

DllCall doesn't support char*, it should be declared as byte* instead.

Share this post


Link to post
Share on other sites

char * is a string anyway.

Share this post


Link to post
Share on other sites

I just test it. It shows @error = 1 which means function call failure.

I'm sure it comes from that line...

Is it possible to let me know what kind of error has occurred?

Also from the help file...

Return Value

Success: @error = 0.

Failure: set @error

@error: 1 unable to use the DLL file,

2 unknown "return type",

3 "function" not found in the DLL file,

4 bad number of parameters.

See remarks.

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