External functions/methods and complex parameters

For questions and postings not covered by the other forums
ConvertFromOldNGs
Posts: 5321
Joined: Wed Aug 05, 2009 5:19 pm

External functions/methods and complex parameters

Postby ConvertFromOldNGs » Fri Aug 07, 2009 11:45 am

by Darren Brown >> Sat, 20 Nov 1999 1:36:57 GMT

Hi,

I would like to call an external 'C' functiion from an NT4.0 Jade5.014 application.

Have got this to work for simple data types but I am not sure how to approach struct's etc - a manual mentioned using 'a Binary reference' but I tried several permutations without any luck.

The signature of the method is:

void blah (struct a * a1, // Input
char * c1, // Output
char * c2, // Output
char * c3); // Output

struct a {
char *ac[100];
}

Can anyone provide me with the corresponding Jade prototype/approach ?

Hope so!

Thanks,

Darren.
darren.brown@abol.net

ConvertFromOldNGs
Posts: 5321
Joined: Wed Aug 05, 2009 5:19 pm

Re: External functions/methods and complex parameters

Postby ConvertFromOldNGs » Fri Aug 07, 2009 11:45 am

by Krull >> Sun, 21 Nov 1999 4:09:51 GMT

Hi Darren,

There are two tricky aspects to defining and calling this external function from JADE:
1) Your input structure consists of an array of char pointers, which need to be initialised. Since the structure contains memory pointers you will not be able to execute the function on a presentation client (the default for an external function in 'smart thin client' mode). This means you will need to specify applicationServerExecution on the external function prototype.

2) When calling blah, the char pointers passed to the 3 output parameters must reference allocated memory of the correct size. Since the function doesn't provide away to specify the maximum buffer lengths for the returned output params you will need to know the size of the data returned in these params in advance.
The signature of the method is:

void blah (struct a * a1, // Input
char * c1, // Output
char * c2, // Output
char * c3); // Output

struct a {
char *ac[100];
}

One possible way to define this function is as follows:

blah( a1: Binary; c1, c2, c3 : String[Blah_Buffer_Length] output) is blah in blahlib applicationServerExecution;

where Blah_Buffer_length is a constant containing the maximum size of character data returned by the function.
You can then call blah as shown in the following sample method:

callBlah();
vars
aStruct : Binary[400]; // 400 = 100 * sizeof(char *)
s1, s2, s3 : String; // passed to output params
inString : String;
i : Integer;begin

inString := "Hello World";

// initialise the pointers in aStruct. Here we use the String::bufferAddress method to access the internal
// pointer of a Jade String variable. For purposes of the example all 100 pointers reference the same string
// note: use of memory pointers in a structure is not transportable across machines.

foreach i in 0 to 99 do
aa[i*4+1:4] := inString.bufferAddress.Binary;
endforeach;

// call blah, note you don't need to use the bufferAddress method to pass the address of the binary
// since JADE will do this for you.
call blah(aStruct, s1, s2, s3);

// display contents of returned params
write s1;
write s2;
write s3;

end;

If the size of the strings returned in the output params can vary between calls, then you could use this alternative prototype:

blah( a1: Binary; c1, c2, c3 : String output) is blah in blahlib applicationServerExecution;

To call this version:

call blah(aStruct, s1.bufferAddress, s2.bufferAddress, s3.bufferAddress);

When using this version, you must ensure that the internal memory for each of the output string params is preallocated. You can do this by growing the Jade string to the corect length:

// grow c1 to 1000 characters
c1[1000] := 0.Character;

ConvertFromOldNGs
Posts: 5321
Joined: Wed Aug 05, 2009 5:19 pm

Re: External functions/methods and complex parameters

Postby ConvertFromOldNGs » Fri Aug 07, 2009 11:45 am

by Krull >> Sun, 21 Nov 1999 4:19:24 GMT

Ooops, sorry about the formatting. I forgot to allow for text wrap at
7 chars. Here is a reformatted sample.

callBlah();
vars
aStruct : Binary[400]; // 400 = 100 * sizeof(char*)
s1, s2, s3 : String; // passed to output params
inString : String;
i : Integer;begin

inString := "Hello World";

// initialise the pointers in aStruct. Here we use the
// String::bufferAddress method to access the internal
// pointer of a Jade String variable. For purposes of the
// example, all 100 pointers reference the same string
// note: use of memory pointers in a structure is not transportable // across machines.

foreach i in 0 to 99 do
aa[i*4+1:4] := inString.bufferAddress.Binary;
endforeach;

// call blah, note you don't need to use the bufferAddress method to // pass the address of the binary, since JADE will do this for you. call blah(aStruct, s1, s2, s3);

// display contents of returned params
write s1;
write s2;
write s3;

end;

ConvertFromOldNGs
Posts: 5321
Joined: Wed Aug 05, 2009 5:19 pm

Re: External functions/methods and complex parameters

Postby ConvertFromOldNGs » Fri Aug 07, 2009 11:45 am

by Krull >> Sun, 21 Nov 1999 4:40:43 GMT

Darren,

Another thought, I'm a bit slow today.
A third alternative that allows the length of the output strings
to vary between calls and avoids the need to use bufferAddress
in the call, is to define the output parameters as io as follows:

blah( a1: Binary; c1, c2, c3 : String io) is blah in blahlib applicationServerExecution;

To call this version, you still need to ensure that the s1, s2 and s3 strings are pre-initialised to the required size, the call is as follows:

call blah(aStruct, s1, s2, s3);

Grow the strings as follows:

// grow s1 to 1000 characters
s1[1000] := 0.Character;


Return to “General Discussion”

Who is online

Users browsing this forum: No registered users and 17 guests