en@frrom
4th June 2009, 12:09
I have a dll function which returns a varying number of arguments to the calling program. The returned variables are string arrays. I don't manage to send this string array back.

I tried a view variations by using put.string.arg(), but no success yet. This is what I tried so far:

1) ret = put.string.arg(22, o.stack.mitm)

This gives a compilation error that only one element is allowed.

2) ret = put.string.arg(22, o.stack.mitm())

This gives a compilation error that ')' not expected (in other words the program expects a certain element when using brackets).

3) for i = 1 to filled.el
ret = put.string.arg(22, o.stack.mitm(1, i))
endfor

In this case the first element of the variable in the calling program is filled over and over again with o.stack.mitm(1, i). In other words, the program does not know in which element of the array to put the given value, so eah time puts it into the first element. All the other elements remain empty.

Please note: the array can contain hundreds of elements, therefor it is not an option to add lots of single element variables to the function.

In the help I don't see any function for passing on arrays. For instance by put.var() there is a function put.indexed.var() but I dount whether this can be of any use in my case...?

Any suggestion would be highly appreciated!!


Kind regards,
Eli Nager

Hitesh Shah
4th June 2009, 13:18
What is the function prototype . I have dll function with ref specification , through which arrays are automatically passed to calling program without user having to do anything.

e.g
sort.grpstr.and.search.position(ref string search_str(),
ref domain tcmcs.s256 grpstr(),long search_len , long grplen , ref long arrctr, ref long srcpos)

OR

sort.grpstr.and.search.position(ref string search_str(),
ref string grpstr(,),long search_len , long grplen , ref long arrctr, ref long srcpos).

Is it something else that u r trying to do .

en@frrom
4th June 2009, 13:24
Hi Hitesh,

Thanks first of all for your reply. Like I wrote in my first post, it concerns a function with a various number of return arguments.

I.e. function extern tccom.dll0001.abc(i.bpid, o.cadr, ...). This prototype means that the minimum arguments required to pass along when calling this function is 2, yet more are allowed (= varying number of arguments). In my case one program will pass another (ref) variable of type string array along, which needs to be filled by the dll function and returned to the program. So the calling function will call something like: tccom.dll0001.abc(tdsls400.bpid, ret.cadr, ret.open.entries()). The ret.open.entries is an array of type string.


Regards,
Eli Nager

Hitesh Shah
4th June 2009, 14:05
As per help , arrays are not allowed . Even generic parse_and_exec_function does not allow array arguments . So with arrays dont think there is a way .

DESCRIPTION
It is possible to enter a varying number of arguments when defining a
function. The function definition looks like:

Example:
function long change.attributes( long id, ... )
{
......
}

The code ... indicates that the number of arguments of this function is
variable: any number of arguments may be added (in this case the
minimum is 1).
The function call must contain all arguments that are required and
determines which arguments the function will use. To allow the use of
an unspecified number of arguments in a function definition, the
following functions have been made. They comprise functions to read
arguments as well as functions to assign values to arguments.

The maximum number of arguments for a function is 255 and usage
of array's is not allowed.

en@frrom
4th June 2009, 14:09
Yes Hitesh, I saw that, but I always claim that where there's a will, there's a way... :)

Hitesh Shah
4th June 2009, 14:33
This should technically work with variable code , dimension and indication to tell the array argument as function argument .

Earlier we had tried arrays with parse_and_exec_function without success. Put.var.indexed / get.var.indexed seems to be promising if u do a bit of re-engineering as to passing it's dimensions , array code etc .

george7a
4th June 2009, 14:45
If I understood your problem correctly, you can write a new wrapper function, add the arguments you need plus the array. In the DLL this new wrapper will call the original one and deal with the array as a global variable. Since the wrapper function is a regular one, it should be able to return the array back..

en@frrom
4th June 2009, 17:09
Thanks George for your post, that is exactly what I did. It's not a neat solution, but it serves its purpose as a workaround...

Thomson S
7th June 2013, 07:39
If I understood your problem correctly, you can write a new wrapper function, add the arguments you need plus the array. In the DLL this new wrapper will call the original one and deal with the array as a global variable. Since the wrapper function is a regular one, it should be able to return the array back..

Hi George,
Can you please explain this little more, I even have a scenario like this. I dont understand what you are coming to say about wrapper function. Please explain me little more.

Thanks in advance.

NPRao
7th June 2013, 23:14
Yes Hitesh, I saw that, but I always claim that where there's a will, there's a way...
Eli,

I like the challenge :) Going through the thread, with some valid limitations and issues with arrays.

You have to send the array argument as a reference variable, then get the max length or individual length of the strings of each row and allocate memory for the specific array dimension.

Here is my code snippet -

function extern void convert.array.1dto2d(
const string sourcestr(),
ref string result(,),
string delimiter(1),
[ref long num.rows,
ref long max.cols] )
{
DLLUSAGE
This function takes a single one dimension array of string with a
separater (,) and then makes a double dimensional array with the
number of elements and the column size equivalent to the longest element.
After the return of the function call Use - standard tools function
array.info(array, nr.dims, dim.array ) to find the array dimensions.
Enhancement to use variable reference arguments to get the array
dimensions instead of using the array.info() function. The variables
num.rows and num.cols also gives the information about the array
dimensions.
Warning: The variable "result" should be declared as based in the
calling program else the bshell gets disconnected.
ENDDLLUSAGE

long num, leng, posn, sublen, counter, num.args
string temp.str(1) based
...
num = num.of.occ.in.line(sourcestr, delimiter)
...
e = alloc.mem(result, leng, num)
...
result(1, counter) = temp.str
...
e = put.long.arg(4, num)
e = put.long.arg(5, leng)