Neal_the_real has asked for the wisdom of the Perl Monks concerning the following question:

Hello out there.

My question is quit simple but is is very difficult (for me) to implement it.

So, i want to read some config_data out of a perl module. In perl it looks like that.

The module:

package MyConfig; use strict; use Exporter; use vars qw(@ISA @EXPORT $var); @ISA = qw(Exporter); @EXPORT = qw($var); $var = "SOME_FOO"; 1;
And the programm:
#!/usr/bin/perl -w use strict; use MyConfig; printf(">%s<\n",$MyConfig::var);
So far, so good. But now I want the same in C. I tried a little bid and thats my C code
#include <stdio.h> #include <stdlib.h> #include <EXTERN.h> #include <perl.h> static PerlInterpreter *my_perl; int main(void) { char *var; my_perl = perl_alloc(); perl_construct(my_perl); var = SvPV_nolen(get_sv("MyConfig::var", TRUE)); printf(">%s<\n", var); return(EXIT_SUCCESS); }
Makefile:
PERL_CCOPTS = `perl -MExtUtils::Embed -e ccopts` PERL_LDOPTS = `perl -MExtUtils::Embed -e ldopts` all: gcc -g -o read_config.o -c read_config.c $(PERL_CCOPTS) gcc -g -o read_config read_config.o $(PERL_LDOPTS)
I get's a Segmentation fault. Hope anyone can help me out :-)

Thanks a lot. Regards Neal

P.S. I know, my english is not the best. So please forgive me.

Replies are listed 'Best First'.
Re: Config Module for C and Perl
by samtregar (Abbot) on Feb 20, 2006 at 19:40 UTC
    Follow the first rule of C - always check your return values! I suspect that either get_sv() or SvPV_nolen is returning NULL. Trying to dereference a NULL pointer is a great way to get a Segmentation Fault.

    As to why they'd return NULL, my guess is it's because you're not loading the MyConfig module. Try something like this before trying to fetch the variable:

      eval_pv("use MyConfig", 1);

    -sam

      Hello samtregar. Your suggestion was a step in the right way. But there was also a few lines lacking for the perl-allocation. Now, I can represent a working C code.
      #include <stdio.h> #include <stdlib.h> #include <EXTERN.h> #include <perl.h> static PerlInterpreter *my_perl; int main(void) { char *var; char *embedding[] = {"", "-e", "0"}; my_perl = perl_alloc(); perl_construct(my_perl); perl_parse(my_perl, NULL, 3, embedding, NULL); perl_run(my_perl); eval_pv("use MyConfig", TRUE); var = SvPV_nolen(get_sv("MyConfig::var", TRUE)); printf(">%s<\n", var); return(EXIT_SUCCESS); }
      Hello samtregar.

      Your suggestion was a step in the right way. But there was also a few lines lacking for the perl-allocation. Now, I can represent a working C code.

      #include <stdio.h> #include <stdlib.h> #include <EXTERN.h> #include <perl.h> static PerlInterpreter *my_perl; int main(void) { char *var; char *embedding[] = {"", "-e", "0"}; my_perl = perl_alloc(); perl_construct(my_perl); perl_parse(my_perl, NULL, 3, embedding, NULL); perl_run(my_perl); eval_pv("use MyConfig", TRUE); var = SvPV_nolen(get_sv("MyConfig::var", TRUE)); printf(">%s<\n", var); return(EXIT_SUCCESS); }