Thanks for the reply,

I am writing some perl bindings for Libnet (should make it to CPAN soon).
However, there are two routines libnet_init_packet and
libnet_destroy_packet. 

init_packet takes a char ** as an argument to allocate it. I tried to
simulate this in perl, so that somebody could, if they wanted to, analyse
the packet in perl.

Example:

#!/usr/bin/perl

use Net::Libnet;

my $packet;

# After this $packet should be defined
init_packet($packet);

## WARNING here $packet should be a char * only
build_packet(....a bunch of options..., $packet);
 
# Here we could print the real packet in HEX instead
print $packet;                                    

..... send the packet ....

# After this $packet should be undef
destroy_packet($packet);

Now... we are lucky here because we know that libnet allocates
LIBNET_MAX_SOMETHING space in the packet. That way the XS wrapper could
allocate a string of this size and return it. But this could change anytime
with newer versions of libnet so I dont think it is a good idea to hardcode
this in XS. 

I made a more simple version by storing the pointer in an integer. But it is
no longer possible to do print $packet... (it just prints the pointer...)

The challenge for me is to try to put as much stuff in the typemap so that I
dont have to do CODE: OUTPUT: all the time. There are like 50+ functions.

I think it's possible, but I dont know how to do it yet (I am learning XS as
fast as I can). 

Daniel Shane

> -----Original Message-----
> From: Tye McQueen [mailto:[EMAIL PROTECTED]]
> Sent: Monday, January 21, 2002 1:30 PM
> To: [EMAIL PROTECTED]
> Cc: [EMAIL PROTECTED]
> Subject: Re: How to malloc a char ** from C to Perl (btw, $! 
> now works,
> thank
> 
> 
> Excerpts from the mail message of Daniel Shane:
> ) 
> ) void init(str)
> )     char *   &str
> ) 
> ) void fill(str, str2)
> )     char *    str
> )     char *    str2
> ) 
> ) void free(str)
> )     char *    str
> ) 
> ) void init(char *str) {
> )     *str = (char *)calloc(20, sizeof(char));
> ) }
> ) 
> ) void fill(char *str, char *str2) {
> )     strcpy(str, str2);
> ) }
> ) 
> ) void free(char *str) {
> )     free(str);
> ) }
> 
> Nope, Perl won't treat as a string any memory that it didn't
> allocate itself.  It will try to reallocate and/or free it for
> any number of reasons.
> 
> I'm not sure why you want to do something like this, but
> you can either store the pointer to the allocated memory
> into something that is relatively opaque to the Perl script
> (such as an integer or the pointer packed into a string),
> or you can use Perl's *PV* routines to allocate the memory
> and let Perl free it when it wants to.
> 
> I'd go into more details but I'll wait until you explain
> why you want this and which way you'd rather go.
> 
> ) Now in perl I could simply do:
> ) 
> ) my $test_string;           # $test_string is undefined...
> ) 
> ) init(\$test_string);       # now $test_string should be 
> defined but empty...
> ) print "$test_string \n";   # Should print nothing...
> 
> No, \$test_string makes a Perl reference which isn't something
> you want to pass to XS code that is expecting a "char *".   Did
> you know that you can modify $test_string even when you write
> 
>     init($test_string)
> 
> ?  Perl passes arguments "by reference" (not to be confused
> with references that Perl creates with \, so I'd say it is
> more accurately expressed as Perl passing arguments by making
> @_ contian _aliases_ to the actual parameters).
> 
> Tye
> 

Reply via email to