[Info-vax] Any Way to Pass Arrays of Strings from C to Basic?
Arne Vajhøj
arne at vajhoej.dk
Thu Nov 7 18:46:15 EST 2019
On 10/31/2019 2:40 PM, Craig Dedo wrote:
> Is there any way to pass arrays of character strings from C to Basic? For both languages I'm using the current versions of the languages:
> VSI C V7.4-002 on OpenVMS Alpha V8.4-2L2
> VSI BASIC V1.8-005 on OpenVMS V8.4-2L2
>
> I need to pass character string variables from a main program or
> procedure written in C to a subroutine written in Basic and get back
> character string data from the Basic subroutine. I had to write the
> subroutine in Basic because it needs to call a utility subroutine in
> Basic that uses arrays of varying-length character strings.
>
> This post is an expansion of my original post on October 21. This
> morning management decided that we will be using multiple instances
> of the same kind of data in one subroutine call. I.e., instead of
> getting all of the information for one part number at a time we will
> be getting the information for up to 1000 part numbers at a time.
>
> Thus, the utility routine that I'm calling from my interface routine
> in Basic will be returning a 2-D array of varying length character
> strings. I'm still going to use an interface routine written in
> Basic so that I can simplify the interface between C and Basic.
>
> In the original problem, using fixed-length character string
> descriptors worked very well for passing the string arguments from
> the calling routine in C to the interface routine in Basic. Now I
> need to write descriptors for arrays of fixed-length character
> strings.
>
> I tried to research this on my own but came up empty. I have read
> thru the text of descrip.h, the latest reference manuals and user
> guides for both Basic and C, and the OpenVMS Programming Concepts
> Manual. Nothing I have found tells me how to fill in all of the
> elements in the array descriptor, only some of them.
For:
sub f(string sa())
print 'lbound = ', lbound(sa)
print 'ubound = ', ubound(sa)
for i = lbound(sa) to ubound(sa)
print sa(i)
next i
end sub
this:
program bmain
external sub f(string dim())
declare string sa(2)
sa(0) = 'A'
sa(1) = 'BB'
sa(2) = 'CCC'
call f(sa())
end program
and:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <descrip.h>
#include <lib$routines.h>
struct dsc$multipliers_1
{
char *dsc$a_a0;
long dsc$l_m[1];
};
struct dsc$bounds
{
long dsc$l_l;
long dsc$l_u;
};
struct str_arr_1
{
struct dsc$descriptor_nca nca;
struct dsc$multipliers_1 m;
struct dsc$bounds b[1];
};
#define ELM 3
void f(struct str_arr_1 *sa);
void def(char *s, struct dsc$descriptor_d *d)
{
int slen;
slen = strlen(s);
lib$sget1_dd(&slen, d);
d->dsc$b_dtype = DSC$K_DTYPE_T;
memcpy(d->dsc$a_pointer, s, slen);
}
int main(int argc,char *argv[])
{
struct dsc$descriptor_d d[3];
struct str_arr_1 sa;
def("A", &d[0]);
def("BB", &d[1]);
def("CCC", &d[2]);
memset(&sa, 0, sizeof(sa));
sa.nca.dsc$w_length = sizeof(struct dsc$descriptor_d);
sa.nca.dsc$b_dtype = DSC$K_DTYPE_DSC;
sa.nca.dsc$b_class = DSC$K_CLASS_NCA;
sa.nca.dsc$a_pointer = (char *)&d[0];
sa.nca.dsc$b_dimct = 1;
sa.nca.dsc$l_arsize = sizeof(d);
sa.m.dsc$a_a0 = (char *)&d[0];
sa.m.dsc$l_m[0] = 8;
sa.b[0].dsc$l_l = 0;
sa.b[0].dsc$l_u = ELM - 1;
f(&sa);
return 0;
}
seems to behave identical here (VMS Alpha,
C 7.3 and Basic 1.7).
Arne
More information about the Info-vax
mailing list