[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]
Re: Inline::C
- From: muppet <scott asofyet org>
- To: Tom Hargreaves <hex freezone co uk>
- Cc: gtk-perl mailing list <gtk-perl-list gnome org>
- Subject: Re: Inline::C
- Date: 06 Mar 2004 23:40:56 -0500
On Sat, 2004-03-06 at 21:31, Tom Hargreaves wrote:
> I don't know if anyone's tried using Inline::C with gtk2-perl; I don't
> recall seeing it mentioned here.
my gut reaction is a loud hiss, followed by a growl. but then i
remember that Inline::C is really handy when all you need is one piddly
little C function, and i come to my senses.
> One thing I'm unsure about is how to portably locate gperl.h: would
> searching @INC be wise? Currently I've just hardcoded the path...
which, of course, is not where it is on my machine, so i had to hack at
it just to run it, and found a few interesting things...
you don't really ever want to use gperl_get_object() by itself; each
extension's main header includes automagically generated wrapper macros
which call it for you, and those macros are used by the generated
typemaps. so, instead of
da = gperl_get_object_check (area, GTK_TYPE_WIDGET);
you want to do
da = SvGtkWidget (area);
but even better than that would be to have Inline::C apply the typemap
for you (as is done in the attached patch)!
this, of course, means you need to find gtk2perl.h and the Gtk2
typemaps, so we're back to your problem about finding a header.
ExtUtils::Depends is gtk2-perl's solution to this. i used a new depends
object to find and collate for me the INC, LIBS, and TYPEMAPS that
Inline::C needs to compile all this stuff.
there's a problem, though; Inline::C's docs say that the TYPEMAPS
parameter takes whatever MakeMaker takes for TYPEMAPS, but this is a
dirty filthy lie -- MakeMaker takes a filename or an array of filenames,
but Inline::C takes only one filename. so, i had to do something
*really* ugly --- compile all the typemaps from Gtk2 and Glib (there are
at least three files) into one temporary typemap file and pass *that* to
Inline::C.
you'll want to fix up this code to make the ExtUtils::Depends stuff run
only when Inline::C needs to compile, but otherwise, the patch attached
should make your previously posted version run "anywhere".
i think this TYPEMAPS thing is a bug in Inline::C, but until that gets
fixed, we may want to consider whether the Evil Magick required to get
ExtUtils::Depends to work with Inline::C and all that should be wrapped
up into ExtUtils::Depends. what think you?
> Finally, a huge thanks to everyone who helped make gtk programming
> this much fun!
hey, thanks for writing a cool program! meander is spiffy.
--
muppet <scott at asofyet dot org>
--- meander.pl 2004-03-06 23:24:02.000000000 -0500
+++ meander-mup.pl 2004-03-06 23:28:42.000000000 -0500
@@ -29,22 +29,65 @@
use constant pi=>4*atan2(1,1);
-my @packages;
-my @incs;
-my @libs;
+my %mfvars; # Makefile Vars
+my $typemap; # dirty hack, see below
BEGIN {
- @packages=qw[glib-2.0 gtk+-2.0];
- @incs=map qx[pkg-config $_ --cflags], @packages;
- @libs=map qx[pkg-config $_ --libs], @packages;
- chomp (@incs, @libs);
- push @incs, "-I/usr/lib/perl5/Glib/Install"; # ewww
+ # ExtUtils::Depends knows how to find the typemaps and headers for the
+ # Gtk2 module and the ones on which it depends (Glib, basically).
+ # use it to get the INC, LIBS, and TYPEMAPS information we need to give
+ # to Inline::C so we can use gtk2-perl functions and such.
+ use ExtUtils::Depends;
+ my $dep = ExtUtils::Depends->new ('Meander', 'Gtk2');
+ %mfvars = $dep->get_makefile_vars;
+
+ # Inline::C's manpage claims that it takes the same value for TYPEMAPS as
+ # MakeMaker, but this is an evil lie --- it takes only a filename string,
+ # whereas MakeMaker takes a string or an array of strings. We'll have to
+ # consolidate the many typemap files from the depends object into one to
+ # appease the fickle Inline. This bites.
+ my %typemap_info;
+ use strict;
+ foreach my $f (@{$mfvars{TYPEMAPS}}) {
+ open IN, $f or die "can't open $f: $!\n";
+ my $cur = '';
+ while (<IN>) {
+ if ($cur eq '') {
+ next unless /^TYPEMAP/;
+ $cur = 'TYPEMAP';
+ } elsif (/^(INPUT|OUTPUT)/) {
+ $cur = $1;
+ } else {
+ push @{$typemap_info{$cur}}, $_;
+ }
+ }
+ close IN;
+ }
+ use File::Temp ':mktemp';
+ $typemap = mktemp ("/tmp/".$0."XXXXXX");
+ open OUT, ">$typemap" or die "can't write temp typemap file: $!";
+ print OUT "# generated by $0 from ".join(" ", @{$mfvars{TYPEMAPS}})."\n\n";
+ foreach my $section (qw(TYPEMAP INPUT OUTPUT)) {
+ print OUT "$section\n";
+ foreach (@{$typemap_info{$section}}) {
+ print OUT $_;
+ }
+ }
+ close OUT;
+}
+END {
+ unlink $typemap;
}
-use Inline C => <<'EOF', CCFLAGS => '-O3', INC => "@incs", LIBS => "@libs";
+use Inline (C => Config =>
+ CCFLAGS => '-O3',
+ INC => $mfvars{INC},
+ LIBS => $mfvars{LIBS},
+ TYPEMAPS => $typemap, #$mfvars{TYPEMAPS}, # $% ^ Inline, see above
+);
+use Inline C => <<'EOF';
-#include <gperl.h>
-#include <gtk/gtk.h>
+#include <gtk2perl.h>
#define THRESH 0.5
@@ -119,7 +162,7 @@
}
}
-int draw_meander (SV *points_ref, SV *area, int xstart, int ystart, int dx, int dy, int maxiter, int l) {
+int draw_meander (SV *points_ref, GtkWidget *area, int xstart, int ystart, int dx, int dy, int maxiter, int l) {
AV *points;
int len;
double *ptr;
@@ -150,7 +193,7 @@
*ptr++=(double)SvNV(*val);
}
- da = gperl_get_object_check (area, GTK_TYPE_WIDGET);
+ da = area;
bufptr = buf;
count = 0;
[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]