SPUG: Re: spug-list-digest V1 #179

Mark Wagner mark at lanfear.net
Fri Mar 15 15:10:18 CST 2002

> I have a small NDBM database that is normally written to by a C application.
> As the keys and values stored in an NDBM database are character strings,
> I'm casting ...  something roughly like.
> 	struct custom_struct {
> 	  some complex struct stuff;
> 	};
> 	datum key, val;
> 	struct custom_struct aaa;
> 	key.dptr="bbb";
> 	key.dsize=strlen(key.dptr);
> 	val.dptr=(char *) &aaa;
> 	val.dsize=sizeof(struct custom_struct);
> 	/* db is pointer to DBM already opened */
> 	dbm_store(db, key, val, DBM_REPLACE);
> Now when I read the data from the database at a later time, I use memcpy
> to move from the stored string back to my struct, as in:
> 	val = dbm_fetch(db, key)
> 	memcpy((char *) &aaa, val.dptr, val.dsize);
> 	/* now work on struct aaa */
> Ok, now for the question.  I'm writing a Perl application that reads from
> the same database.  However, if I tie a %hash to the ndbm file and then
> print out the keys and values, the values are garbled.  Is there a Perl
> equivalent to the C memcpy for byte string copies?

You're playing with fire delving into C structs this way.
Quoting from

	[T]he elements of a struct are laid out in the order given in
	the declararation [sic] of the structure. The compiler is not
	allowed to reorder the elements, but it is allowed to insert
	padding between the elements, in order to make the access to
	the structure elements more efficient and to support machines
	that require data to be aligned.

So you might be running into padding which you may be able to fix. Your
code will be compiler- and machine-dependent but that may be okay for you
and the the people that have to get the code to work on another machine.

If you still can't get perl to grok them the next easiest option may
be to write some XS code to call some C functions to extract the
fields you need in perl.

The long-term solution may be to write some C functions that store the
structure in a string through a member-wise copy into it, recursing at
each member struct so that the string is nothing but strings and atomic
C data types. Handing that string with perl would be much easier: using
unpack would be straightforward. Plus your C code could be compiled with
different compilers. If you wanted to run on different architectures
you would need to use the hton* functions to take care of endian issues.

Mark Wagner mark at lanfear.net

 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     POST TO: spug-list at pm.org       PROBLEMS: owner-spug-list at pm.org
      Subscriptions; Email to majordomo at pm.org:  ACTION  LIST  EMAIL
  Replace ACTION by subscribe or unsubscribe, EMAIL by your Email-address
 For daily traffic, use spug-list for LIST ;  for weekly, spug-list-digest
     Seattle Perl Users Group (SPUG) Home Page: http://seattleperl.org

More information about the spug-list mailing list