2009-05-21 7 views
1

Ich habe ein Problem, auf das ich keine Antwort finden kann.Wie kann ich Win32-Module nur integrieren, wenn ich mein Perl-Skript unter Windows ausführe?

Mit Perl muss ich ein Skript über Windows und Unix-Plattformen verwenden. Das Problem ist, dass wir unter Windows Win32-spezifische Module wie Win32::Process verwenden, und diese Module existieren nicht unter Unix.

Ich brauche eine Möglichkeit, diese Win32-Module nur unter Windows zu integrieren.

if($^O =~ /win/i) 
{ 
    use win32::process qw(CREATE_NEW_CONSOLE); 
} 
else 
{ 
    #unix fork 
} 

Das Problem liegt in der Verwendung von Anweisung für Windows. Egal was ich versuche das kompiliert nicht unter Unix.

ich dynamisches evals verwendet hat versucht, erfordert, BEGIN usw.

Gibt es für dieses Problem eine gute Lösung? Jede Hilfe wird sehr geschätzt.

Vielen Dank im Voraus,

Dan


Update:

Ein Mitarbeiter mir dies der richtige Weg, es zu tun hingewiesen.

require Win32; 
require Win32::Process; 

my $flag = Win32::Process::CREATE_NEW_CONSOLE(); 

Win32::Process::Create($process, 
    $program, 
    $cmd, 
    0, 
    $flag, ".") || die ErrorReport(); 

print "Child started, pid = " . getPID() . "\n"; 

Vielen Dank für Ihre Hilfe!

Dan

Antwort

7

use wird zur Kompilierzeit ausgeführt.

Stattdessen tun:

BEGIN { 
    if($^O eq 'MSWin32') { 
     require Win32::Process; 
     # import Win32::Process qw(CREATE_NEW_CONSOLE); 
     Win32::Process->import(qw/ CREATE_NEW_CONSOLE /); 
    } 
    else { 
     #unix fork 
    } 
} 

die perldoc for use See.

Siehe auch perlvar unter $^O.


Update:

Als Sinan Unur weist darauf hin, ist es am besten indirect object syntax zu vermeiden.

Ich benutze direkte Methodenaufrufe in jedem Fall, außer mit Aufrufen an import. Wahrscheinlich, weil import als ein eingebauter Maskerade. Da import wirklich eine Klassenmethode ist, sollte sie als Klassenmethode aufgerufen werden.

Danke, Sinan.

Auch auf Win32-Systemen müssen Sie sehr vorsichtig sein, dass Sie die Großschreibung Ihrer Modulnamen korrekt erhalten. Falsche Großschreibung bedeutet, dass Symbole nicht korrekt importiert werden. Es kann hässlich werden. use win32::process scheint zu funktionieren.

+4

Vermeiden Sie die indirekte Objektsyntax: Win32 :: Process-> import (qw (CREATE_NEW_CONSOLE)); –

3

Sind Sie sicher, win32 :: Prozess kann auf OSX geladen werden? "Darwin" passt zu Ihrem/win/i.
Sie können http://search.cpan.org/dist/Sys-Info-Base/ verwenden, die versucht, das Richtige zu tun.

Abgesehen davon, können Sie ein Beispiel für den tatsächlich verwendeten Code, die Fehlernachricht, die Sie erhalten, und für die Unix-Plattform (uname -a) veröffentlichen?

0

Was ist mit einem Parser, der die Datei auf jedem Betriebssystem ändert?

Sie könnten Ihre Perl-Datei über ein configure-Skript parsen, das auf beiden Betriebssystemen funktioniert, um Perl mit den richtigen Use-Klauseln auszugeben. Sie könnten sogar die Parse-Aktion im ausführbaren Skript begraben, um den Code zu starten.

Ursprünglich dachte ich an Precompiler-Anweisungen von C würde den Trick machen, aber ich kenne Perl nicht sehr gut.

0

Hier ist eine Antwort auf Ihre zweite Reihe von Fragen:

Sie verwenden strict und warnings?

Haben Sie ein ErrorReport() Unterprogramm definiert? ErrorReport() ist nur ein Beispiel in der Synopse für Win32::Process.

CREATE_NEW_CONSOLE ist wahrscheinlich nicht numerisch, weil es nicht richtig importiert wurde. Überprüfen Sie die Großschreibung in Ihrem Anruf an import.

Vergleichen Sie diese Einzeiler:

C:\>perl -Mwin32::process -e "print 'CNC: '. CREATE_NEW_CONSOLE; 
CNC: CREATE_NEW_CONSOLE 

C:\>perl -Mwin32::process -Mstrict -e "print 'CNC: '. CREATE_NEW_CONSOLE; 
Bareword "CREATE_NEW_CONSOLE" not allowed while "strict subs" in use at -e line 1. 
Execution of -e aborted due to compilation errors. 

C:\>perl -MWin32::Process -e "print 'CNC: '. CREATE_NEW _CONSOLE; 
CNC: 16 
0

Sie könnten nur Ihre Plattform-spezifischen Code platzieren innerhalb eines eval{}, und für einen Fehler überprüfen.

BEGIN{ 
    eval{ 
    require Win32::Process; 
    Win32::Process->import(qw'CREATE_NEW_CONSOLE'); 
    }; 
    if([email protected]){ # [email protected] is $EVAL_ERROR 

    # Unix code here 

    } 
} 
Verwandte Themen