THMMY.gr

Ηλεκτρονικοί Υπολογιστές και Τεχνικά Θέματα => C / C++ / C# => Topic started by: Nessa NetMonster on March 17, 2008, 13:42:16 pm



Title: Πρόγραμμα C που καλεί άλλο πρόγραμμα C
Post by: Nessa NetMonster on March 17, 2008, 13:42:16 pm
Έχω δύο αρχεία .c, ας πούμε το parent.c και το child.c, και θέλω όταν τρέχω το parent κάποια στιγμή να εκτελεί ως "υπορουτίνα" το child (μεταφέρει στο child την εκτέλεση και το child κάνει exit στο parent). Νομίζω ότι αυτό γίνεται με τις συναρτήσεις spawn. Έλα όμως που κάθε φορά που πάω να το εκτελέσω το εκτελώ κανονικά! Συγκεκριμένα μου βγάζει κωδικό λάθους errno=ENOMEM, δηλ. σύμφωνα με τους οδηγούς μου "Not enough core".

Μήπως δίνω λάθος arguments στο child; Μήπως είναι πρόβλημα λειτουργικού; Τι μπορεί να προκαλεί αυτό το σφάλμα; Το child από μόνο του λειτουργεί κανονικά, και το parent βρίσκει το αρχείο στο current directory.

Χρησιμοποιώ τη spawnl. Συγκεκριμένα, του δίνω κάτι σα spawnl(P_WAIT,"CHILD.C","hello",NULL); και το child έχει σαν arguments είτε (int n, char *ch) είτε (char *ch) [έχω δοκιμάσει και τα δύο].


Title: Re: Πρόγραμμα C που καλεί άλλο πρόγραμμα C
Post by: SolidSNK on March 17, 2008, 13:52:20 pm
fork() anyone? Αυτό είναι το σωστό system call για να δημιουργεις child proccesses....

Δεν μπορώ να σου τπτ αλλο από το

%man fork

και τπτ online documentation :)
Να σου πω την αληθεια δεν την ηξερα τη spawn, αλλά ο κλασσικός low-lvl τρόπος είναι η fork() ...

Α και το child.c δε μου φαίνεται για πρόγραμμα αλλά απλως για ένα αρχείο κειμένου if u know what I mean ;)
Δλδ εκτός και αν αποθήκευσες το εκτελέσιμο ως child.c, το βρίσκω τελείως απίθανο η spawnl να παίρνει αρχείο κειμένο ως argument...


Title: Re: Πρόγραμμα C που καλεί άλλο πρόγραμμα C
Post by: Nessa NetMonster on March 18, 2008, 00:21:04 am
Δε γίνεται να συμβουλεύομαι online documentation για τεχνικούς λόγους (δες άλλο thread :-[)...

Τώρα κατάλαβα πώς λειτουργεί το πράγμα... πρέπει το parent με κάποιον τρόπο να κάνει πρώτα compile το child και μετά να το καλέσει. Πώς καλώ το αντίστοιχο πρόγραμμα (tcc) κολλώντας δίπλα το "child.c";


Title: Re: Πρόγραμμα C που καλεί άλλο πρόγραμμα C
Post by: SolidSNK on March 18, 2008, 01:06:09 am
Με τα variants του exec:

Code:
#include <unistd.h>

       extern char **environ;

       int execl(const char *path, const char *arg, ...);
       int execlp(const char *file, const char *arg, ...);
       int execle(const char *path, const char *arg,
                  ..., char * const envp[]);
       int execv(const char *path, char *const argv[]);
       int execvp(const char *file, char *const argv[]);

μπορεις να τρεξεις όποιο πρόγραμμα θες. Απλά πρέπει πρώτα να χρησιμοποιήσεις τη fork(), γιατί η execl() δε δημιουργει ενα child proccess. αλλά  κανει replace την υπαρχουσα proccess. Αρα μετά το system call, θα αγνοηθει οποιοσδηποτε κώδικας από κάτω από την execl() αφού η proccess τερματίζεται...

Δες λίγο πως δουλεύω εγώ με μια child proccess στο linux:

Code:
#include <stdio.h>
#include <unistd.h>

int main (void) {
pid_t pid;
int s = 5;
pid = fork();
if (pid > 0) {
//Eimaste sth child
                execlp ("ls" , "ls" , "-al" , (char*)0);
} else if (pid == 0) {
//Eimaste sth parent
printf("Why hello there\n");
}
fprintf(stdout, "s is %d\n", s);
}

Θα σου φαίνεται περίεργο...
Εδώ με τη fork δημιουργω μια process με ενα συγκεκριμενο pid, και σχεδον simultaneously εκετελούνται και στη parent κ sth child αυτά που είναι μέσα στα if ...

Ουσιαστικά , με τη fork(), όλος ο υπόλοιπος κώδικας θα εκτελεστεί σε 2 proccesses, η αρχική και η άλλη που δημιουργήθηκε από τη fork(). Το κόλπο είναι σε μιά από τις 2  να εκτελέσεις το εξωτερικό πρόγραμμα με τη execl, και μετά αφού θα γίνει αυτό που θες, η μια proccess θα τερματιστεί (έτσι δουλεύει η execl)  και ο υπόλοιπος κώδικας θα εκτελεστεί κανονικά! Αν δεν το κάνεις αυτό, το παρακάτω θα σε διαφωτίσει...

Code:
#include <stdio.h>
#include <unistd.h>


int main (void) {
int s = 5;
execlp ("ls" , "ls" , "-al" , (char*)0);
fprintf(stdout, "s is %d\n", s);
}

το τελευταίο fprintf θα αγνοηθεί...


Title: Re: Πρόγραμμα C που καλεί άλλο πρόγραμμα C
Post by: Nessa NetMonster on March 18, 2008, 01:27:47 am
Δεν καταλαβαίνω :-[

Ο κώδικας της pid πού είναι;


Title: Re: Πρόγραμμα C που καλεί άλλο πρόγραμμα C
Post by: Nessa NetMonster on March 18, 2008, 01:34:56 am
Κάτι αρχίζω να πιάνω...


Title: Re: Πρόγραμμα C που καλεί άλλο πρόγραμμα C
Post by: SolidSNK on March 18, 2008, 01:44:56 am
Από τη στιγμή που κάνεις fork() , δημιουργειται μια νεα process με ομοια στοιχεία με την 'parent' (που δεν είναι εντελως parent). Ότι κάνει παρακάτω το πρόγραμμα εκτελείται ΚΑΙ ΣΤΙΣ ΔΥΟ. Η μόνη διαφορά ανάμεσα σε parent κ child ειναι το pid που επέστρεψε η fork κατα την ανάθεση... H parent έχει 0 και η child έναν θετικό αριθμό. Οτιδήποτε άλλο υπάρχει όμοια και στις δύο processes (μεταβλητές, συναρτήσεις, σταθερές). Άρα με μια if condition μπορεις να ελέγξεις αποκλειστικά τι γίνεται στη parent ή στη child! Στο παράδειγμα μου, h execl , που εκτελείται μόνο στη 'child' , αντικαθιστα την process την οποία την καλεί (th child) κάνει ότι είναι να κάνει κ μετά τερματίζεται. Άρα κανονικά συνεχίζεται η ροή του προγραμματος. μετά το if...

Αυτό που δεν έχω καταλάβει είναι τι ακριβώς θες να κάνεις... άμα θες να κάνεις include απλά τον κώδικα δεν έχουν καμία σχέση τα από πάνω. 'Πρόγραμμα που καλεί άλλο πρόγραμμα C' είναι ο τίτλος του topic... άρα φαντάζομαι πως απλώς θες να εκτελεσθεί κάτι επιπλέον στο κυρίως πρόγραμμα σου. Τα παραπάνω σε καλύπτουν και παρόλο που πρέπει να σου φαίνονται περίεργα, σε fork() exec κ pipe() έχουν βασιστεί τα UNIX λειτουργικά...

Φαντάζομαι θα έχεις απορίες και δεν έιμαι ακόμα σε ικανό επίπεδο στο system programming (γιατί αυτό κανεις) για να σε καλύψω στα σίγουρα.


Title: Re: Πρόγραμμα C που καλεί άλλο πρόγραμμα C
Post by: Nessa NetMonster on March 18, 2008, 02:58:44 am
Δεν ξέρω, ίσως να το έχω πάρει από την αρχή τελείως λάθος... Εκτελώ ένα πρόγραμμα. Έχω ένα αρχείο .c το οποίο τροποποιείται από το πρόγραμμα εκείνη την ώρα. Αφού τροποποιήσω και κλείσω το αρχείο αυτό, θέλω κάποια στιγμή το πρόγραμμα να το εκτελέσει.

Κάπου στην πορεία συνειδητοποίησα ότι πρέπει να είναι πρώτα εκτελέσιμο το αρχείο για να το εκτελέσει (είπαμε είμαι άσχετη :P), οπότε πρέπει το πρόγραμμα να κάνει και compile. Αυτό όμως είναι πάλι το ίδιο πρόβλημα, αφού πρέπει μέσω του προγράμματος να εκτελέσω το tcc.exe με όρισμα το αρχείο που θέλω.


Title: Re: Πρόγραμμα C που καλεί άλλο πρόγραμμα C
Post by: Nessa NetMonster on March 18, 2008, 22:41:33 pm
Α-χουμ...

Εκτελώ g=spawnl(P_WAIT,"TCC.EXE","SYNART.C",NULL);

Ο κωδικός λάθους που μου βγάζει είναι Not enough core.

Γιατί δε με θέλει η C; :(


Title: Re: Πρόγραμμα C που καλεί άλλο πρόγραμμα C
Post by: SolidSNK on March 18, 2008, 22:59:42 pm
Μα γιατί τέτοιο κόλλημα με τη spawnl... Από όσο ξέρω δεν είναι standard function  :-\

και νομίζω πρέπει να βάλεις και full path name εκει στο tcc.exe ;)

btw καλα σκέφτεσαι ...


Title: Re: Πρόγραμμα C που καλεί άλλο πρόγραμμα C
Post by: Nessa NetMonster on March 19, 2008, 00:59:25 am
Μπα, το αρχείο το βρίσκει, αλλιώς η errno θα μου έδινε File not found. Κάτι με την αναμονή ίσως να παίζει...

BTW και με την exec έχω τα ίδια αποτελέσματα... τον προγραμματισμό μου μέσα :-\ :-\ :-\


Title: Re: Πρόγραμμα C που καλεί άλλο πρόγραμμα C
Post by: Nessa NetMonster on March 28, 2008, 14:58:24 pm
Ρε παιδιά θα τρελαθώ... δε δουλεύει ούτε η system! Για την ακρίβεια, έκανα copy-paste το παράδειγμα από το Help όπου χρησιμοποιούσε τη system για να καλέσει τη dir και να σου βγάλει κατάλογο αρχείων, και πάλι όταν πάω να το εκτελέσω μου λέει ότι δεν έχει αρκετή μνήμη! Copy-paste από το παράδειγμα ακριβώς είχα κάνει ^banghead^


Title: Re: Πρόγραμμα C που καλεί άλλο πρόγραμμα C
Post by: SolidSNK on March 28, 2008, 15:00:49 pm
Ποιον compiler έχεις??


Title: deleted
Post by: BOBoMASTORAS on March 28, 2008, 16:07:53 pm
deleted


Title: Re: Πρόγραμμα C που καλεί άλλο πρόγραμμα C
Post by: Nessa NetMonster on March 28, 2008, 16:57:15 pm
Οτιδήποτε από τα δύο μου κάνει.


Title: Re: Πρόγραμμα C που καλεί άλλο πρόγραμμα C
Post by: marauber on March 28, 2008, 17:44:45 pm
Ε αυτό είναι το μόνο εύκολο. Γράφεις ένα header file b.h για το b.c, και #include "b.h" στο a.c.


Title: Re: Πρόγραμμα C που καλεί άλλο πρόγραμμα C
Post by: Nessa NetMonster on March 28, 2008, 18:04:01 pm
Ναι αλλά μήπως έτσι δε θα μπορώ να το αλλάξω όσο τρέχει το πρόγραμμα;


Title: Re: Πρόγραμμα C που καλεί άλλο πρόγραμμα C
Post by: Aurelius on March 28, 2008, 18:09:06 pm
Προφανως δεν μπορεις να το αλλαξεις.

Δεν μας λες περιπου τι θες να κανεις.


Title: Re: Πρόγραμμα C που καλεί άλλο πρόγραμμα C
Post by: Nessa NetMonster on March 28, 2008, 18:11:14 pm
Βασικά εκεί που θα ήθελα να με βοηθήσετε είναι να μου βρείτε έναν τρόπο να καλώ exe. Από εκεί και πέρα δεν υπάρχει πρόβλημα, απλά θα εκτελέσω πρώτα την "tcc.exe child.c" και μετά την "child.exe" που θα έχει δημιουργηθεί.


Title: Re: Πρόγραμμα C που καλεί άλλο πρόγραμμα C
Post by: Nessa NetMonster on March 28, 2008, 18:14:05 pm
@Aurelius:
Εκτελώ ένα πρόγραμμα. Έχω ένα αρχείο .c το οποίο τροποποιείται από το πρόγραμμα εκείνη την ώρα. Αφού τροποποιήσω και κλείσω το αρχείο αυτό, θέλω κάποια στιγμή το πρόγραμμα να το εκτελέσει.

Δηλαδή δεν υπάρχει κάποιο έτοιμο πρόγραμμα που μπορώ να κάνω include, αλλά φτιάχνω ένα πρόγραμμα από την αρχή και μετά το εκτελώ.


Title: Re: Πρόγραμμα C που καλεί άλλο πρόγραμμα C
Post by: SolidSNK on March 28, 2008, 18:15:25 pm
Καταρχάς αυτά που λέει ο Nh είναι για linux. Δε ξέρω αν λειτουργούν σε win.

Λάθος είναι για όλα τα UNIX :P  ^jerk^
Αυτά που λέω θα της έλυναν τα προβλήματα, που να ήξερα ο καψερός ότι είχε XP...

Όσο για το πρόβλημα σου νέσσα, απότι φαίνεται χρησιμοποιείς σωστές functions, μάλλον πρέπει να καταλάβουμε γιατί βγάζει τα errors. Δε postαρεις το κώδικα σου λιγάκι?


@Aurelius:
Εκτελώ ένα πρόγραμμα. Έχω ένα αρχείο .c το οποίο τροποποιείται από το πρόγραμμα εκείνη την ώρα. Αφού τροποποιήσω και κλείσω το αρχείο αυτό, θέλω κάποια στιγμή το πρόγραμμα να το εκτελέσει.

Δηλαδή δεν υπάρχει κάποιο έτοιμο πρόγραμμα που μπορώ να κάνω include, αλλά φτιάχνω ένα πρόγραμμα από την αρχή και μετά το εκτελώ.

object file? <-- google it
Έτσι κάνεις 'include' πρόγραμμα (πολύ χονδροειδώς) αλλά δεν μπορείς να το αλλάξεις....


Title: Re: Πρόγραμμα C που καλεί άλλο πρόγραμμα C
Post by: Aurelius on March 28, 2008, 18:24:35 pm
Ο μονος τροπος να προσδιοριζεται το αποτελεσμα οχι στον compile ειναι με κληρονομικοτητα, abstract κλασεις κτλ. Κατα τα αλλα δεν νομιζω να μπορεις να κανεις αυτο που θες, δηλαδη να φτιαχνεις το προγραμμα σου, γραμμες κωδικα με βαση κατι αλλο.

Το μονο που μπορω να σκεφτω ειναι να παραγει το προγραμμα σου ενα αρχειο, στο οποιο θα παραγει τις γραμμες με καποιο τροπο που του οριζεις εσυ και μετα να το κανεις compile σαν bash script. Αυτο βεβαια στο linux και δεν ξερω αν θα δουλευε.

Κατ τα αλλα, τοσο τυχαια ειναι τα αποτελεσματα που δεν θες να λαβεις διαφορετικες περιπτωσεις μεσα στον κωδικα, αλλα θες αυτος να αλλαζει.

Δεν μας λες καλυτερα πιο συγκεκριμενα γιατι το θες, μηπως γινεται κι αλλιως?


Title: Re: Πρόγραμμα C που καλεί άλλο πρόγραμμα C
Post by: Nessa NetMonster on March 28, 2008, 18:31:11 pm
Θέλω να γράφει ο χρήστης μια μαθηματική συνάρτηση του x και να γράφεται σε ένα αρχείο το αποτέλεσμα για κάποια x. Ο μόνος εύκολος τρόπος να γίνει αυτό είναι να γράφεται ένα πρόγραμμα επιτόπου που θα περιλαμβάνει σε μια γραμμή τη συνάρτηση αυτή. Πχ δίνει ο χρήστης το string "cos(2*x)" και γράφεται στο child.c "y=cos(2*x);" σε μια προκαθορισμένη θέση. Μετά το πρόγραμμα child εκτελείται και συνεχίζει το parent.


Title: Re: Πρόγραμμα C που καλεί άλλο πρόγραμμα C
Post by: Zarathoustra on March 28, 2008, 19:11:04 pm
Θέλεις να κάνεις  parsing (http://en.wikipedia.org/wiki/Parsing) μαθηματικών εκφράσεων,λοιπόν.Αυτό είναι συγκεκριμένο προγραμματιστικό πρόβλημα που έχει επιλυθει, όχι όμως με την ανορθόδοξη μέθοδο που προτείνεις(στην ουσία θέλεις να χρησιμοποιήσεις τον parser του compiler...)


Title: Re: Πρόγραμμα C που καλεί άλλο πρόγραμμα C
Post by: Nessa NetMonster on March 28, 2008, 20:32:55 pm
Ξέρεις κάποιον ευκολότερο τρόπο; ::)