IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Compiler "à la volée"


Sujet :

C++

  1. #1
    Membre expérimenté Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Points : 1 732
    Points
    1 732
    Par défaut Compiler "à la volée"
    Bonjour à tous.
    J'aimerai faire en C++ (non managé) une chose que je fais en C# :
    Je génère du code (une classe par exemple), puis j'utilise un objet qui permet d'invoquer le compilateur C#, ca me fait une DLL que je charge aussitot dans le process, un petit coup de reflexion et hop la nouvelle classe s'intègre à l'application.

    Seulement voila, je ne me voit pas trop distribuer tout un compilo avec mon programme. Donc j'ai cherché un compilateur "intégrable" mais je n'ai rien trouvé...

    Résultat je me dis que je ne vais pas avoir le choix, je dois distribuer un compilo avec ou du moins permettre a l'utilisateur de spécifié le compilo installé sur sa machine.
    Seulement voila, j'ai ouïe dire qu'il n'est pas bon de mixer les compilos (en gros il faudrait que la compilation a la volée utilise le même compilo que celui qui a servit à compiler l'application).

    Dans quelle mesure c'est impactant ?

    Sinon j'ai fais un premier jet avec le compilo de Visual Studio 2010 Ultimate, mais ca gauffre violemment dans la fonction CreateProcess. Il me dit qu'il y a une exception non gérée, violation d'accès lors de l'écriture, et le débogueur m'amène dans le fichier dbgheap.c, ligne 239. Je capte pas comment ca se fait.

    Le code utilisé est le suivant :
    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
     
    #include <iostream>
    #include <fstream>
     
    #include <windows.h>
     
    int main(int argc, wchar_t* argv[])
    {
    	// Création d'un fichier source
    	std::ofstream file("test.cpp", std::ios::out);
    	if(!file)
    	{
    		std::cerr << "Impossible d'ouvrir le fichier test.cpp" << std::endl;
    		return -1;
    	}
    	file << "#include <iostream>" << std::endl;
    	file << "void hello() { std::cout << \"hello !\" << std::endl; }" << std::endl;
    	file.close();
     
    	STARTUPINFO         siStartupInfo;
    	PROCESS_INFORMATION piProcessInfo;
     
    	memset(&siStartupInfo, 0, sizeof(siStartupInfo));
    	memset(&piProcessInfo, 0, sizeof(piProcessInfo));
     
    	siStartupInfo.cb = sizeof(siStartupInfo);
    	wchar_t* env[2];
    	env[0] = L"PATH=%PATH%;D:\\softs\\Microsoft Visual Studio 2010\\Common7\\IDE";
    	env[1] = 0;
     
    	int result = CreateProcess(0,
    		L"D:\\softs\\Microsoft\\ Visual\\ Studio\\ 2010\\VC\\bin\\cl.exe /EHsc test.cpp",
    		0,
    		0,
    		FALSE,
    		CREATE_DEFAULT_ERROR_MODE,
    		0,
    		L"D:\\programmation\\projects\\dynamic_compil\\dynamic_compil",
    		&siStartupInfo,
    		&piProcessInfo);
     
    	if(!result)
    	{
    		std::cerr << GetLastError() << std::endl;
    	}
    	return 0;
    }

    Merci de votre aide

  2. #2
    Membre expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Points : 3 159
    Points
    3 159
    Par défaut
    Hello

    On fait ça dans ma boîte, générer du code qui est ensuite compilé à la volée.

    Citation Envoyé par ctxnop Voir le message
    je dois distribuer un compilo avec ou du moins permettre a l'utilisateur de spécifié le compilo installé sur sa machine.
    Seulement voila, j'ai ouïe dire qu'il n'est pas bon de mixer les compilos (en gros il faudrait que la compilation a la volée utilise le même compilo que celui qui a servit à compiler l'application).
    A cause de ce problème notamment, on ne charge pas dynamiquement la DLL créée, on compile un exécutable qui sera lancé à part et dont on va lire la sortie.

  3. #3
    screetch
    Invité(e)
    Par défaut
    pour ton crash:
    An environment block can contain either Unicode or ANSI characters. If the environment block pointed to by lpEnvironment contains Unicode characters, be sure that dwCreationFlags includes CREATE_UNICODE_ENVIRONMENT. If this parameter is NULL and the environment block of the parent process contains Unicode characters, you must also ensure that dwCreationFlags includes CREATE_UNICODE_ENVIRONMENT.
    deja ca c'est pas bon
    de plus, un environnement ressemble a ca:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    "env1=value1\0env2=value2\0env3=value3\0\0"
    (unicode ou ansi)

  4. #4
    Membre expérimenté Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Points : 1 732
    Points
    1 732
    Par défaut
    Désolé, je n'ai pas du tout eu le temps hier de continuer sur ce sujet.

    Effectivement, j'ai complètement zapé le flag CREATE_UNICODE_ENVIRONMENT, même pas fait gaffe.
    Ce n'était pas la seule erreur, je créais la variable d'environnement mais je ne la passait pas à la fonction, il faut passer je ne passais pas non plus le chemin de l'exécutable à lancer, pensant que la commande était suffisante...

    Enfin bref, ca fonctionne maintenant, je n'ai plus qu'a affiner tout ca et faire de testes de compatibilité entre les compilos.

    Merci du coup de main

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Avril 2011
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations forums :
    Inscription : Avril 2011
    Messages : 5
    Points : 5
    Points
    5
    Par défaut
    Bonjour,

    J'essaye de compiler une DLL C++ lors de l'execution de mon programme, mais j'ai quelque problème. Peut tu mettre les différentes erreurs que tu avais faite dans le forum et m'expliquer a quoi il servent.

    Merci d'avance.

  6. #6
    Membre expérimenté Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Points : 1 732
    Points
    1 732
    Par défaut
    Les erreurs que j'avais faites et leurs explications/résolutions sont toutes sur ce post.
    Je ne suis pas aller beaucoup plus loin sur le sujet, le problème imposant d'utiliser le même compilateur pour l'application "principale" et la partie compilée a la volée est trop contraignante par rapport a ses avantages.
    A la base je voulais faire ca pour utiliser le C++ en tant que langage de "script", mais au final il est bien plus simple d'utiliser vraiment un truc fait pour ca, genre le lua, le python ou même un binding CLR pour scripter en .Net.

  7. #7
    Membre extrêmement actif
    Homme Profil pro
    Graphic Programmer
    Inscrit en
    Mars 2006
    Messages
    1 579
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Graphic Programmer
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 579
    Points : 4 054
    Points
    4 054
    Par défaut
    sinon tu peux écrire un interpréteur.

    T'a peu être pas besoin de toute les specif du c++

    au pire ya des interpréteur c++. va sur ce lien ils en parlent : http://www.velocityreviews.com/forum...gine-in-c.html

  8. #8
    Membre expérimenté Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Points : 1 732
    Points
    1 732
    Par défaut
    Citation Envoyé par cuicui78 Voir le message
    sinon tu peux écrire un interpréteur.

    T'a peu être pas besoin de toute les specif du c++
    Oula, la flemme d'écrire un tel truc alors qu'il existe tout plein de choses pour le faire.
    En plus je sais bien que si j'écris un interpréteur "avec juste ce que j'ai besoin", je sais pertinemment que je vais sans cesse atteindre les limites de ce que j'avais définit au début et devoir tout recommencer.
    Donc je préfère un truc supportant un vrai langage complet.

    Citation Envoyé par cuicui78 Voir le message
    au pire ya des interpréteur c++. va sur ce lien ils en parlent : http://www.velocityreviews.com/forum...gine-in-c.html
    Ouais, c'est une idée, je ne savais pas qu'il existait des interpréteurs c++, je jetterai un oeil a l'occasion, pour l'instant le projet est en stand by, je n'ai plus du tout de temps à y consacrer. Merci pour le lien en tout cas, fort intéressant

  9. #9
    Membre confirmé Avatar de themadmax
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    446
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 446
    Points : 496
    Points
    496
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    #include <string>
    #include <iostream>
    #include <fstream> 
    #include <windows.h>
     
    using namespace std ;
     
    typedef int (*MYPROC)(int); 
     
    int main(int argc, char** argv)
    {
    	string dllstr("__declspec( dllexport ) int MyFuncInc(int a) { return ++a; }" );
    	ofstream out("dll.c");
    	out << dllstr << endl ;
    	out.close();
    	system( "cl.exe -o dll.dll /EHsc dll.c /link /DLL /OUT:dll.dll" );
    	MYPROC MyFuncInc = (MYPROC)GetProcAddress( LoadLibrary("dll.dll"), "MyFuncInc" );
    	cout << MyFuncInc(41) << endl ;
    	return 0;
    }
    Perso c'est juste pour le fun car je vois pas vraiment l'intéré de faire de genre de chose, soit tu fait du scripting soit du distribue des DLL.

  10. #10
    Membre expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Points : 3 159
    Points
    3 159
    Par défaut
    Citation Envoyé par themadmax Voir le message
    Perso c'est juste pour le fun car je vois pas vraiment l'intéré de faire de genre de chose, soit tu fait du scripting soit du distribue des DLL.
    Ca a énormément d'intérêt quand tu dois faire de lourds calculs numériques sur un modèle théorique. Tu transforme ton modèle en code C (ou C++), que tu compiles à la volée et que tu exécutes pour récupérer le résultat.

    Evidemment, on est obligé de lancer l'exécution dans un processus externe, ce qui oblige à mettre en place un système de communication. Ce serait plus simple à mettre en place si le code compilé pouvait être chargé à la volée.

  11. #11
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Ouais faut que le code soit bien lourd pour que ça soit rentable.
    Pour des calculs légers à "moyen", embarquer Python serait à mon avis plus approprié quand on a besoin d’exécuter du code à la volée...

  12. #12
    Membre expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Points : 3 159
    Points
    3 159
    Par défaut
    Citation Envoyé par poukill Voir le message
    Ouais faut que le code soit bien lourd pour que ça soit rentable.
    Oui, c'est le cas quand tu résout de gros systèmes d'équations différentielles par exemple.

  13. #13
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par jblecanard Voir le message
    systèmes d'équations différentielles
    Les règles du forum interdisent les vulgarités
    (vieux souvenir d'étudiant : EDP == )

  14. #14
    Membre expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Points : 3 159
    Points
    3 159
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Les règles du forum interdisent les vulgarités
    (vieux souvenir d'étudiant : EDP == )
    Moi non plus j'ai jamais trop aimé ça . Ce n'est pas moi qui me suit farci le code.

  15. #15
    Membre confirmé Avatar de themadmax
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    446
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 446
    Points : 496
    Points
    496
    Par défaut
    Citation Envoyé par jblecanard Voir le message
    Ca a énormément d'intérêt quand tu dois faire de lourds calculs numériques sur un modèle théorique. Tu transforme ton modèle en code C (ou C++), que tu compiles à la volée et que tu exécutes pour récupérer le résultat.
    Tu as fait un logiciel en C++, tu le distribut. Ton client doit lui même écrire des "pluging" en C++, cela reviens de fournir un SDK?

    Citation Envoyé par jblecanard Voir le message
    Evidemment, on est obligé de lancer l'exécution dans un processus externe, ce qui oblige à mettre en place un système de communication. Ce serait plus simple à mettre en place si le code compilé pouvait être chargé à la volée.
    Regarde mon code il compile une DLL, puis la charge et l’exécute.

  16. #16
    Membre expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Points : 3 159
    Points
    3 159
    Par défaut
    Tu n'as pas compris.

    Il s'agit de code généré dynamiquement par l'utilisateur, pendant l'utilisation du logiciel, et ce de manière transparente. Il crée un modèle, et pour le résoudre, le logiciel génère du code. Il pourrait générer du python au autre, bien sûr, mais le but est un max de perfos donc on génère du C. Ca crée des tas de fichiers C illisibles pour un esprit censé mais qui compilés et exécutés produisent un résultat exploitable.

    Citation Envoyé par themadmax Voir le message
    Regarde mon code il compile une DLL, puis la charge et l’exécute.
    Oui mais on retombe sur le problème de compatibilité entre compilateurs. Ta solution impose au client d'utiliser le même compilateur que celui que tu as utilisé pour lui livrer ton soft.

  17. #17
    Membre confirmé Avatar de themadmax
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    446
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 446
    Points : 496
    Points
    496
    Par défaut
    Citation Envoyé par jblecanard Voir le message
    Oui mais on retombe sur le problème de compatibilité entre compilateurs. Ta solution impose au client d'utiliser le même compilateur que celui que tu as utilisé pour lui livrer ton soft.
    Une DLL est un format d’échange de format exécutable, si tu respect les convention d'appel il est normalement indépendant du compilateur. Par exemple le moindre programme que tu compile est liée avec les DLL windows, pourtant tu peux les utilisées avec GCC, TCC...

  18. #18
    Membre expérimenté Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Points : 1 732
    Points
    1 732
    Par défaut
    C'est vrai en C, beaucoup moins pour du C++.
    Si dans ton programme principale tu déclare une classe A, et que tu génère a la volée une classe B héritant de A, il n'y a pas qu'une question de convention d'appel.
    Les compilateurs sont plus ou moins "libre" de la façon dont ils traduisent ca en code machine. Par exemple, j'avais lu je ne sais plus où que certains compilateurs placent la vtable en début d'objet et d'autres en fin. Ce qui fait que l'objet B ne peut être utilisé dans le code principal car il a un format différent.
    Si je me goure et qu'il est effectivement possible de compiler et exécuter un code a la volé sans se soucier du compilateur, ca m'intéresse grandement, ne serait-ce que pour le plaisir de le mettre en place.

  19. #19
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Avec une API C, ok. Avec du C++, c'est plus délicat : l'ABI (interface binaire) dépend du compilateur.
    Ainsi entre GCC et Visual par exemple, la décoration de nom (name mangling) n'est pas la même.
    Plus délicat, en cas d'héritage virtuel, une des deux implémentations utilise le même vpointeur pour la vtable et l'offset. L'autre implémentation utilise un vpointeur pour la vtable et un second vpointeur pour l'offset.
    Un pointeur de fonction virtuelle est aussi différent (cf ici)
    Sans compter les implémentations différentes de la STL et autres joyeusetés

    [edit] grilled

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Quote et double quote
    Par aktos dans le forum Langage
    Réponses: 8
    Dernier message: 05/01/2007, 19h55

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo