Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]1141[/thread]

Perl und C++ verheiraten: als Perl Modul

Tags: Ähnliche Threads

Leser: 3


<< >> 8 Einträge, 1 Seite
cbxk1xg
 2006-02-10 17:28
#11348 #11348
User since
2003-10-20
496 Artikel
BenutzerIn
[default_avatar]
Hallo, Freunde der Sonne!

Ich muß demnächst für ein Projekt diverse Perl Module erstellen. Wir wir alle wissen hat Perl seine Stärken, aber auch seine Schwächen. Und da ich das ganze Projekt nicht alleine Programmieren werde, überlege ich seit einiger Zeit gewisse Teile aus Performanegründen lieber in C++ schreiben zu lassen. Viele CPAN Module sind ja auch ein Mix aus Perl und C (oder C++).

Meine Frage ist nun, eie spreche ich in einem Perl Modul den compilierten C++ Code an? Muß ich mich da auf eine C++ Klasse beziehen? Wie binde ich das ein? Auf der anderen Seite muß ja das C++ Programm auch meine perligen Eingaben verstehen und mir was perliges zurückgeben.

Fragen über Fragen... Das macht Kopf Aua! :O

Gibt es da irgendwo verständliche Tutorials? Das Wiki habe ich schon durch, aber nix verstanden. Liegt wohl auch daran, daß ich kein C kann.  :0
murphy
 2006-02-10 18:41
#11349 #11349
User since
2004-07-19
1776 Artikel
HausmeisterIn
[Homepage]
user image
Die Kommunikation zwischen Perl und kompiliertem Code ist nicht ganz trivial. Außerdem gibt's verschiedene Varianten, wie man sie bewerkstelligen kann. Am einfachsten ist es wahrscheinlich, wenn Du ein Modul wie CPAN:Inline::CPP verwendest, das alles automagisch erledigt.

Willst du mit "Bordmitteln" auskommen, so solltest Du dich mit XS vertraut machen und dazu folgende Perldocs wälzen: <!--pod1--><a href="//www.perldoc.com/perl5.8.0/pod/perlxstut.html" target="_blank">perldoc <!--pod2-->perlxstut<!--pod3--></a><!--pod4-->, <!--pod1--><a href="//www.perldoc.com/perl5.8.0/pod/perlxs.html" target="_blank">perldoc <!--pod2-->perlxs<!--pod3--></a><!--pod4-->, <!--pod1--><a href="//www.perldoc.com/perl5.8.0/pod/perlguts.html" target="_blank">perldoc <!--pod2-->perlguts<!--pod3--></a><!--pod4-->. Letztere ist auch allgemein wichtig, wenn dein C(++) Code selbst mit Perldatenstrukturen herumspielen will und nicht alles an der Schnittstelle Perl<->C(++) hin- und herkonvertiert werden soll.

Schließlich gibt es noch Tools wie swig, die ähnliches wie XS leisten, nur anders.
When C++ is your hammer, every problem looks like your thumb.
cbxk1xg
 2006-02-10 19:42
#11350 #11350
User since
2003-10-20
496 Artikel
BenutzerIn
[default_avatar]
OK, das waren erschlagend viele Infos. :-)

Wie ist das denn ganz allgemein bei den Modulen im CPAN gelöst? Da gibt es doch auch einen Haufen an Modulen, insbesondere die ganzen Mathe-Module, die ihre Berechnung in einem C(++) Teil des Moduls ausführen. So weit ich weiß wird das vor allem wegen der Flieskommagenauigkeit und der Performance gemacht. Diese Module müssen dann mit makefile kompiliert werden, bevor sie vom Perl Interpreter ausgeführt werden. Die übliche Prozedur halt.

Wie muß ich mir das denn vorstellen? Habe ich dann nach dem installieren ein "plain Perl" Modul und eine EXE in C(++) die untereinander Daten austauschen?

In meinem Fall sieht es halt so aus, daß ein anderer Programmierer gerne Module in C(++) für mein Perl Programm schreiben will. Der Ablauf ist in etwa so:
Code: (dl )
1
2
3
4
5
-----------------      --------------      ---------------------
|               |  ->  |            |  ->  |                   |
| Hauptprogramm |      | Perl Modul |      | Funktion in C(++) |
|               |  <-  |            |  <-  |                   |
-----------------      --------------      ---------------------


Ein Beispiel, wenn auch nicht auf mein Projekt zutreffend, wäre zum Beispiel ein Mathemodul das mir Pi auf eine beliebige Stelle ausrechnet. Den rechenintensiven Teil würde ich dann gerne in einen C(++) Teil auslagern und as Ergebnis als Hash im Perl Modul weiterverabeiten.
murphy
 2006-02-10 21:41
#11351 #11351
User since
2004-07-19
1776 Artikel
HausmeisterIn
[Homepage]
user image
Ich habe jetzt keine Statistik zur Hand, aber ich glaube, die meisten Module, die "native" Code verwenden, benutzen die XS Schnittstelle.

Der Grund ein XS Modul zu schreiben ist in aller Regel entweder eine existierende C-Bibliothek, die gut ist, und die man nicht in Perl neuschreiben will, oder aber die mögliche höhere Geschwindigkeit von "native" Code. Man muss hier aber durchaus abwägen, ob eine Lösung mit "native" Code wirklich schneller ist. In der Regel ist das nur dann der Fall, wenn das Programm, das man im Endeffekt schreibt auch wirklich viel Zeit bei rechenintensiven Aufgaben im "native" Code verbringt, also zum Beispiel riesige Matrixmultiplikationen hier ausführt. Gibt es hingegen sehr viel "Hin und Her" zwischen Perlcode und "native" Code, so kann die Notwendigkeit der Datenkonvertierung an der Schnittstelle Perl <-> "native" Code das Programm sogar viel langsamer als eine pure Perllösung machen.

Die Funktionsweise von XS Modulen ist, grob skizziert, so: Es gibt ein pures Perlmodul, das als Platzhalter für den eigentlichen "native" Code dient, aber auch zusätzlichen unterstützenden Perlcode enthalten kann. Daneben gibt es eine XS-Datei, bei der es sich im wesentlichen um C-Code mit zusätzlichen Präprozessorfeatures handelt. Diese XS-Dateien werden von einem mit Perl mitgelieferten Präprozessor zunächst in pures C übersetzt und anschließend durch den systemeigenen C-Compiler geschickt. Die resultierenden Objekte werden in eine dynamische Bibliothek gelinkt. Wir das Modul dann von Perl geladen, so wird nicht nur der Platzhalter, sondern auch die dynamische Bibliothek in den Speicher geladen und eine Initialisierungsroutine fügt die definierten XS-Subroutinen zu Perl hinzu.

Alternativ zum erstellen einer dynamischen Bibliothek können die XS-Subroutinen auch statisch direkt in den Perlinterpreter gelinkt werden.
When C++ is your hammer, every problem looks like your thumb.
esskar
 2006-02-10 21:46
#11352 #11352
User since
2003-08-04
7321 Artikel
ModeratorIn

user image
mit XS wird immer eine library erstellt (unter windows dll, unter linux ist das eine .a oder .so glaube ich), die dann von Perl bi der Verwendung deines Moduls geladen wird. Mir hat das Buch "Extending and embedding Perl" viel gebracht. Ich hab aber Vorteil, dass ich eh aus der C/C++ Ecke komme.\n\n

<!--EDIT|esskar|1139600837-->
Neal_the_real
 2006-02-21 15:11
#11353 #11353
User since
2006-02-21
21 Artikel
BenutzerIn
[Homepage] [default_avatar]
Ha genau an so einer Sache bin ich auch dran.

Und zwar ist das so:
Ich habe ein Perl Modul in dem all die Konfigurationen stehen. Datenbanken, Services, IP Adressen usw. Dieses Modul, nennen wir es einmal MyConfig.pm ,stellt also fuer alle Perlscripte eine Zentrale Configuration dar. So weit so gut. Jetzt moechte ich aber auch gerne meine C Programme mit den Services versorgen koennen.
Ich habe schon mal 'a weng rumprobiert das auch funktioniert, was ich noch nicht kann ist Datenstruktuern von Perl in C zu exportieren (array, hash, objekte). Mit string's geht es aber. Hier das Beispiel:

Das Perlmodul MyConfig.pm
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
package MyConfig;

use strict;
use Exporter;
use vars qw(@ISA @EXPORT $var);

@ISA = qw(Exporter);
@EXPORT = qw($var);

$var = "SOME_FOO";

1;

Und das C Programm
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#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);
}

Und das Makefile (WICHTIG vor dem gcc ... muss ein <TAB> sein)
Code: (dl )
1
2
3
4
5
6
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)


Evtl. koennte mir da jemand auf die spruegen helfen wie ich ein array von perl in C exportioeren kann.


--
Gruss Neal
--
Gruss Neal

Hier koennte ein schlauer Spruch stehen!
esskar
 2006-02-21 15:25
#11354 #11354
User since
2003-08-04
7321 Artikel
ModeratorIn

user image
[quote=Neal_the_real,21.02.2006, 14:11]Und das Makefile (WICHTIG vor dem gcc ... muss ein <TAB> sein)[/quote]
das ist bei makefiles so üblich
Neal_the_real
 2006-02-21 15:40
#11355 #11355
User since
2006-02-21
21 Artikel
BenutzerIn
[Homepage] [default_avatar]
Ja, das schon. Aber als ich vor ein paar Jahren mit C angefangen habe wusste ich das nicht und ich Stunden damit verpracht bis ich es zum laufen gebracht habe. Deswegen schreibe ich das immer dazu. ;)

--
Gruss Neal
--
Gruss Neal

Hier koennte ein schlauer Spruch stehen!
<< >> 8 Einträge, 1 Seite



View all threads created 2006-02-10 17:28.