[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