comp.lang.idl-pvwave archive
Messages from Usenet group comp.lang.idl-pvwave, compiled by Paulo Penteado

Home » Public Forums » archive » Re: Importing data from C/C++ to IDL when type is only known at runtime
Show: Today's Messages :: Show Polls :: Message Navigator
E-mail to friend 
Switch to threaded view of this topic Create a new topic Submit Reply
Re: Importing data from C/C++ to IDL when type is only known at runtime [message #48492] Fri, 28 April 2006 08:20 Go to next message
kathryn.ksm is currently offline  kathryn.ksm
Messages: 10
Registered: April 2006
Junior Member
Hi Nigel,

Thanks so much for taking the time to respond to my post and suggest a
solution. I have started playing around with what you suggest and it
looks promising, although a bit unpleasant and error-prone, as you say.
Thanks for clarifying how the IDL_ImportArray function works. It
would have taken me much longer to figure all of this out on my own!

Cheers,

Kathryn
Re: Importing data from C/C++ to IDL when type is only known at runtime [message #48522 is a reply to message #48492] Thu, 27 April 2006 05:09 Go to previous messageGo to next message
Nigel Wade is currently offline  Nigel Wade
Messages: 286
Registered: March 1998
Senior Member
kathryn.ksm@gmail.com wrote:

> Hi Folks,
>
> I'm trying to write a DLM that uses existing C/C++ libaries to read
> data in from files that have a custom (and fairly complex) format.
> This is my first attempt at doing anything serious with IDL and I'm
> having a hard time figuring out what's possible and what isn't. So far
> most of what I've tried doesn't seem to be! So I could use some help.
>
> My existing C code reads selected portions of the data files into a set
> of arrays, where the data type is specified at run-time by the user.
> So, on the C side of things, I have an array of void pointers that
> point to dynamically allocated arrays with various types and sizes
> depending on what the user asked for.
>
> What I need to do is get this data into variables of appropriate types
> in an interactive session in IDL. Ideally, what I would like to do is
> to define and fill a set of nested structures in the DLM code at
> run-time, and return a single structure variable to the IDL session.
> This doesn't seem to be possible though. I can see how I could define
> such a structure at run-time using an array of IDL_STRUCT_TAG_DEFs and
> IDL_MakeStruct, but I don't see any way to fill that structure without
> creating an analogous structure in C in advance (which doesn't seem
> doable, but maybe I'm wrong about that).
>

It's possible, but tiresome and error prone.

If we take one of the examples from the External Ref Guide:

static IDL_MEMINT one = 1;
static IDL_MEMINT tag2_dims[] = { 3, 2, 3, 4};
static IDL_MEMINT tag3_dims[] = { 1, 10 };
static IDL_STRUCT_TAG_DEF s_tags[] = {
{ "TAG1", 0, (void *) IDL_TYP_LONG},
{ "TAG2", tag2_dims, (void *) IDL_TYP_FLOAT},
{ "TAG3", tag3_dims, (void *) IDL_TYP_STRING},
{ 0 }
};
typedef struct data_struct {
IDL_LONG tag1_data;
float tag2_data [4] [3] [2];
IDL_STRING tag_3_data [10];
} DATA_STRUCT;
static DATA_STRUCT s_data;
void *s;
IDL_VPTR v;

/* Create the structure definition */
s = IDL_MakeStruct(0, s_tags);
/* Import the data area s_data into an IDL structure,
note that no data are moved. */
v = IDL_ImportArray(1, &one, IDL_TYP_STRUCT,
(UCHAR *) &s_data, 0, s);

As you've pointed out, it's fairly easy to create the s_tags array dynamically,
and so create the IDL structure tags dynamically. The problem is the s_data
structure, which would need to be defined in advance, at compile time.

However, the s_data structure is only a convenience. All that gets passed to
IDL_ImportArray is a pointer to an area of static memory. The IDL_ImportArray
doesn't care how you fill that area of memory, all it requires is that the
right data is in each "slot". So s_data can be a pointer to an area of memory,
allocated by malloc, which is then populated by writing the appropriate data
values into it via some pointer. This is the bit that's messy and error prone.

The IDL variable, v, returned by IDL_ImportArray is actually using the area of
memory which is passed into it (pointed to by s_data) so you can write whatever
you want into that memory at any time. The trick is knowing where to write
what. With a C structure which maps the IDL structure this is easy. With
dynamic data you need to use a pointer and offset to determine where to write.
You can handle this manually, by determining for yourself where within the data
you need to write a particular element (highly error prone, but quick), or you
can use the function IDL_StructTagInfoByName which will tell you the offset of
particular tag name within the structure.

The big problem which now remains is to determine how much data needs to be
allocated to store the dynamic structure. The only way I can think how to do
this, in the generic case, is to first determine the number of tags using
IDL_StructNumTags. Then get the location and type of the last structure member
using IDL_StructTagInfoByIndex. Use the offset returned by that function, plus
the size of the structure member returned in the var parameter, to calculate
the total size of memory required.


--
Nigel Wade, System Administrator, Space Plasma Physics Group,
University of Leicester, Leicester, LE1 7RH, UK
E-mail : nmw@ion.le.ac.uk
Phone : +44 (0)116 2523548, Fax : +44 (0)116 2523555
Re: Importing data from C/C++ to IDL when type is only known at runtime [message #48532 is a reply to message #48522] Wed, 26 April 2006 05:43 Go to previous messageGo to next message
Robbie is currently offline  Robbie
Messages: 165
Registered: February 2006
Senior Member
I'm sure that there are a myriad of ways to approach this problem, each
with varying degrees of pain and frustration.

Here's an another option to consider (unless it is what you are
attempting to explain in option 3).

You can allocate either:

(A) A structure with values as IDL pointers
struct = {MYSTRUCT, a: ptr_new(/ALLOCATE_HEAP), $
b: ptr_new()/ALLOCATE_HEAP, c: ptr_new(/ALLOCATE_HEAP)}
*struct.a = a
*struct.b = b
*struct.c = c

(B) An array of IDL pointers
array = ptrarr(3,/ALLOCATE_HEAP)
*array[0] = a
*array[1] = b
*array[2] = c

In this example you need to set the variables a, b and c from the C
side. You can then use IDL_ExecuteStr() to execute the above code to
build the IDL variable you want.

Hope this helps,

Robbie
Re: Importing data from C/C++ to IDL when type is only known at runtime [message #48552 is a reply to message #48492] Tue, 02 May 2006 01:33 Go to previous message
Nigel Wade is currently offline  Nigel Wade
Messages: 286
Registered: March 1998
Senior Member
kathryn.ksm@gmail.com wrote:

> Hi Nigel,
>
> Thanks so much for taking the time to respond to my post and suggest a
> solution. I have started playing around with what you suggest and it
> looks promising, although a bit unpleasant and error-prone, as you say.
> Thanks for clarifying how the IDL_ImportArray function works. It
> would have taken me much longer to figure all of this out on my own!
>

Getting external data into IDL can be a minefield. Probably the two worst things
to get right are dynamic arrays of structures and arrays within structures.

The mapping of an IDL structure to a C structure is fairly trivial, provided you
know what you are doing. You need to be sure you understand the internal
padding in the structures, and be aware that the code may well not work on a
different platform. For dynamic structures the same mapping can always be
achieved with pointers, but this is even more error prone, and a lot more care
has to be taken with padding as you have to do this every time, during
execution, rather than just once in the design.

The documentation in the IDL External Ref Guide is pretty comprehensive, but the
relevant details you need are not always easy to find. It can be quite "chatty"
at times, and vital pieces of information are often hidden away in the middle
of sentences buried in a discussion of some esoteric flag. It pays to read the
section on IDL types and variables in it's entirety, several times, to make
sure you've found all there is in there.

--
Nigel Wade, System Administrator, Space Plasma Physics Group,
University of Leicester, Leicester, LE1 7RH, UK
E-mail : nmw@ion.le.ac.uk
Phone : +44 (0)116 2523548, Fax : +44 (0)116 2523555
  Switch to threaded view of this topic Create a new topic Submit Reply
Previous Topic: Re: map_set stereographic projection
Next Topic: IDL licensing question

-=] Back to Top [=-
[ Syndicate this forum (XML) ] [ RSS ] [ PDF ]

Current Time: Wed Oct 08 17:48:01 PDT 2025

Total time taken to generate the page: 0.00525 seconds