2009-05-21 5 views
1

J'ai un problème auquel je n'arrive pas à trouver de réponse.Comment puis-je inclure des modules Win32 uniquement lorsque j'utilise mon script Perl sous Windows?

Avec Perl, j'ai besoin d'utiliser un script sur Windows et les plateformes Unix. Le problème est que sous Windows, nous utilisons des modules Win32-spécifiques tels que Win32::Process, et ces modules n'existent pas sous Unix.

J'ai besoin d'un moyen d'inclure ces modules Win32 uniquement sur Windows.

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

Le problème réside dans cette instruction d'utilisation pour Windows. Peu importe ce que j'essaie cela ne compile pas sur unix.

J'ai essayé d'utiliser evals dynamique, nécessite, BEGIN, etc.

est-il une bonne solution à ce problème? Toute aide est la bienvenue.

Merci à l'avance,

Dan


Mise à jour:

Un collègue de travail m'a fait remarquer c'est la bonne façon de le faire.

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"; 

Merci à tous pour votre aide!

Dan

Répondre

7

use est exécuté au moment de la compilation.

faire au lieu:

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 
    } 
} 

Voir la perldoc for use.

Voir aussi perlvar sur $^O.


Mise à jour:

Comme Sinan Unur souligne, il est préférable d'éviter indirect object syntax.

J'utilise des appels de méthode directe dans tous les cas, sauf avec des appels au import. Probablement parce que import mascarades en tant que built-in. Puisque import est vraiment une méthode de classe, elle devrait être appelée en tant que méthode de classe.

Merci, Sinan. De plus, sur les systèmes Win32, vous devez faire très attention à ce que la majuscule des noms de vos modules soit correcte. La casse incorrecte signifie que les symboles ne seront pas importés correctement. Ça peut devenir moche. use win32::process peut sembler fonctionner correctement.

+4

Évitez la syntaxe d'objet indirect: Win32 :: Process-> import (qw (CREATE_NEW_CONSOLE)); –

3

Êtes-vous sûr win32 :: processus peut être chargé sur OSX? "darwin" correspond à votre/win/i.
Vous pouvez utiliser http://search.cpan.org/dist/Sys-Info-Base/ qui essaie de faire la bonne chose. Cela dit, pouvez-vous poster un exemple du code que vous utilisez réellement, le message d'échec que vous recevez, et sur quelle plateforme unix (uname -a)? Qu'en est-il un analyseur qui modifie le fichier sur chaque OS?

0

Vous pouvez analyser votre fichier perl via un script configure qui fonctionne sur les deux systèmes d'exploitation pour sortir perl avec les clauses Use appropriées. Vous pouvez même enterrer l'action d'analyse dans le script exécutable pour lancer le code. A l'origine je pensais à des directives de précompilateur de C qui feraient l'affaire, mais je ne connais pas très bien perl.

0

est ici une réponse à votre deuxième série de questions:

utilisez-vous strict et warnings?

Avez-vous défini un sous-programme ErrorReport()? ErrorReport() est juste un exemple dans le synopsis pour Win32::Process.

CREATE_NEW_CONSOLE n'est probablement pas numérique car il n'a pas été importé correctement. Vérifiez la capitalisation dans votre appel au import.

Comparer ces one-liners:

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

Vous pouvez placer votre plate-forme simplement le code spécifique à l'intérieur d'un eval{}, et vérifier une erreur.

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

    # Unix code here 

    } 
} 
Questions connexes