Partage
  • Partager sur Facebook
  • Partager sur Twitter

libe57 trop gros fichiers

9 novembre 2018 à 10:29:10

Bonjour à tous! Ce message s'adresse particulièrement aux personnes qui ont utilisés la libe57 (je pense qu'il y en a pas beaucoup ... :( ).
En regardant le tutoriel j'ai réussi à lire et écrire des fichiers.
Mais maintenant j'ai un problème de taille, c'est à dire que j'essaie de lire un fichier qui fait 50Go, et dans le tutoriel, ils font des
std::vector.resize(x);
à tout va. En gros y'a 1 vector pour X, un pour Y, un pour Z, un pour l'intensité et 3 pour la couleur (rouge, vert, bleu). Sauf que chacun à la taille du nombre de points que j'ai (et j'ai plusieurs milliards de points). Donc forcement j'ai un bad_alloc un moment. (Je précise que le e57 est un scan unique apres avoir été unifié).

Ce que j'aimerai faire c'est pouvoir lire par petit morceaux les points, donc par exemple, je reserve num_points_total / 8, je lis tous ces points, je les écris dans un fichier (par exemple), puis je lis les num_points_total / 8 points suivant et je continue jusqu'a la fin. ça m'éviterait de devoir devoir resize sur des nombres beaucoup trop grand...

Mais je ne trouve pas de moyen de faire. Est-ce que ça se joue sur la fonction
ReadData3DGroupsData // Qui me renvoie que le fait que j'ai 1 seul group a chaque fois...

?


Voilà le code que j'essaie d'utiliser actuellement si jamais ... (mais je ne suis pas sûr que ce soit utile)

void main(){
{
	e57::Reader eReader(_name);
	eReader.GetE57Root(rootHeader);
	guid = rootHeader.guid;
	coordinateMetadata = rootHeader.coordinateMetadata;
		
	e57::Data3D scanHeader;
	int scanIndex = 0;
	eReader.ReadData3D(scanIndex, scanHeader);
	int64_t nColumn, nRow, nPoints, nGroupsSize, nCountsSize;
	bool bColumnIndex = false;

	eReader.GetData3DSizes(scanIndex, nRow, nColumn, nPoints, nGroupsSize, nCountsSize, bColumnIndex);

	int cpt = 4;
	nRow = nPoints;
	nColumn = 1;
	nRow = nRow / cpt;
	nGroupsSize = cpt;
	int64_t nSize = nRow;


	std::vector<int8_t> isInvalidData;
	if (scanHeader.pointFields.cartesianInvalidStateField) {
		isInvalidData.resize(nSize);
	}

	std::vector<double> xData, yData, zData;
	xData.resize(nSize);
	yData.resize(nSize);
	zData.resize(nSize);


	std::vector<double> intData;	
	double          intRange = 0;
	double          intOffset = 0;
	intData.resize(nSize);
	intRange = scanHeader.intensityLimits.intensityMaximum - scanHeader.intensityLimits.intensityMinimum;
	intOffset = scanHeader.intensityLimits.intensityMinimum;

	std::vector<uint16_t> redData, greenData, blueData;
	int32_t         colorRedRange = 1;
	int32_t         colorRedOffset = 0;
	int32_t         colorGreenRange = 1;
	int32_t         colorGreenOffset = 0;
	int32_t         colorBlueRange = 1;
	int32_t         colorBlueOffset = 0;

	redData.resize(nSize);
	greenData.resize(nSize);
	blueData.resize(nSize);
	colorRedRange = scanHeader.colorLimits.colorRedMaximum - scanHeader.colorLimits.colorRedMinimum;
	colorRedOffset = scanHeader.colorLimits.colorRedMinimum;
	colorGreenRange = scanHeader.colorLimits.colorGreenMaximum - scanHeader.colorLimits.colorGreenMinimum;
	colorGreenOffset = scanHeader.colorLimits.colorGreenMinimum;
	colorBlueRange = scanHeader.colorLimits.colorBlueMaximum - scanHeader.colorLimits.colorBlueMinimum;
	colorBlueOffset = scanHeader.colorLimits.colorBlueMinimum;

	std::vector<int64_t> idElementValue;
	std::vector<int64_t> startPointIndex;
	std::vector<int64_t> pointCount;


	if (nGroupsSize > 0)
	{
		idElementValue.resize(nGroupsSize);
		startPointIndex.resize(nGroupsSize);
		pointCount.resize(nGroupsSize);

		for (int i = 0; i < nGroupsSize; ++i) {
			startPointIndex[i] = (nPoints / cpt) * i;
			pointCount[i] = nPoints / cpt;
			idElementValue[i] = (nPoints / cpt) * i;
		}

		if (!eReader.ReadData3DGroupsData(scanIndex, nGroupsSize, idElementValue.data(),
			startPointIndex.data(), pointCount.data()))
			nGroupsSize = 0;
	}



	std::vector<int32_t>rowIndex;
	std::vector<int32_t>columnIndex;
	rowIndex.resize(nSize);
	columnIndex.resize(nSize);
	int compteur = 0;
	std::ofstream writed("e57/Writed.xyz");

	while (compteur < cpt) {
	


		e57::CompressedVectorReader dataReader = eReader.SetUpData3DPointsData(
			compteur,                      //!< data block index given by the NewData3D
			nRow,                           //!< size of each of the buffers given
			xData.data(),                          //!< pointer to a buffer with the x data
			yData.data(),                          //!< pointer to a buffer with the y data
			zData.data(),                          //!< pointer to a buffer with the z data
			isInvalidData.data(),          //!< pointer to a buffer with the valid indication
			intData.data(),                        //!< pointer to a buffer with the lidar return intesity
			NULL,
			redData.data(),                        //!< pointer to a buffer with the color red data
			greenData.data(),                      //!< pointer to a buffer with the color green data
			blueData.data(),                       //!< pointer to a buffer with the color blue data
			NULL,
			NULL,
			NULL,
			NULL,
			NULL,
			rowIndex.data(),                       //!< pointer to a buffer with the rowIndex
			columnIndex.data()                     //!< pointer to a buffer with the columnIndex
		);

		int64_t         count = 0;
		unsigned        size = 0;
		int                     col = 0;
		int                     row = 0;

		while (size = dataReader.read())
		{
			//std::cout << dataReader.read() << std::endl;
			for (long i = 0; i < size; i++)
			{
				if (columnIndex.data())
					col = columnIndex[i];
				else
					col = 0;        //point cloud case

				if (rowIndex.data())
					row = rowIndex[i];
				else
					row = count;    //point cloud case

					
					writed << xData[i] << " " << yData[i] << " " << zData[i];



					        //Normalize intensity to 0 - 1.
					double intensity = (intData[i] - intOffset) / intRange;
					writed << " " << intData[i] << '\n';

					                //Normalize color to 0 - 255
					//int red = ((redData[i] - colorRedOffset) * 255) / colorRedRange;
					//int green = ((greenData[i] - colorGreenOffset) * 255) / colorBlueRange;
					//int blue = ((blueData[i] - colorBlueOffset) * 255) / colorBlueRange;
					//writed << " " << red << " " << green << " " << blue << '\n';
					

				count++;
			}
		}

		compteur++;
		dataReader.close();
	}

}



P.S : Oui, je n'ai pas fais tous les tests préconisés, parceque j'aimerai d'abord réussir à faire ce que je veux et qu'avec mon fichier test, je sais qu'il n'y a pas de problèmes.
Pour le moment, ça écris 4 fois les même point dans mon fichier "writed"

-
Edité par KirbXCoucou 9 novembre 2018 à 10:30:27

  • Partager sur Facebook
  • Partager sur Twitter

« Je n’ai pas besoin de preuve. Les lois de la nature, contrairement aux lois de la grammaire, ne permettent aucune exception. »
D. Mendeleïev

9 novembre 2018 à 11:59:50

Si les performances sont pas critique, pourquoi ne pas compiler en 64bits, étendre la taille maximale du swap, et faire le traitement tout d'un coup ?

Avec les 2 actions précédentes, il est fort peu probable d'avoir encore un "bad_alloc".

  • Partager sur Facebook
  • Partager sur Twitter
Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
9 novembre 2018 à 12:38:58

!!!!!!!!!!!!
C'est compilé en 64bits! Mais par contre, je savais pas qu'on pouvais étendre la taille maximale du swap!! Comment fait-on ça? :o
On peut le faire en script?

-
Edité par KirbXCoucou 9 novembre 2018 à 12:39:48

  • Partager sur Facebook
  • Partager sur Twitter

« Je n’ai pas besoin de preuve. Les lois de la nature, contrairement aux lois de la grammaire, ne permettent aucune exception. »
D. Mendeleïev

9 novembre 2018 à 13:59:03

Pour ma part je pense qu'il serait mieux de tenter de résoudre ton problème, c'est à dire lire des gros fichier par chunk. 

voilà un thread qui peut t'intéresser: https://stackoverflow.com/questions/34751873/how-to-read-huge-file-in-c

Pour résumer: tu peut faire du memory mapping avec mmap par exemple. Tu retrouve le même principe sur de l'envoie CPU-GPU.

Au delà de lire le fichier et de le charger en RAM,  compte tu faire un rendu graphique aussi ? Car là tu vas te retrouver avec la même problématique coté VRAM.

Pour moi c'est un peu le principe d'un lecteur vidéo, on se ballade dans un fichier, on décompresse une ou plusieurs frames (dans ton cas pas, on lirais juste) et on les upload sur le GPU. Du coup ton bottleneck par exemple serait la lecture le disque du coup tu pourrais faire du buffering si tu ne veut pas que ton rendu rame (tu prendrais des frames d'avance). Pour ce qui est de l'upload coté GPU là il y a d'autre tactique. Mais bon je m'étale pas sachant que je ne sais même pas si tu vas faire du rendu graphique.

Je m'avance un peu bien sur, mais souvent quand on a un point cloud on a bien envie de le voir :-)

-
Edité par vac 9 novembre 2018 à 14:02:00

  • Partager sur Facebook
  • Partager sur Twitter
9 novembre 2018 à 14:15:48

>Comment fait-on ça? :o

Ça dépend de ton OS.

>On peut le faire en script?

Pourquoi faire ?

C'est à faire une fois.

Après, il faut aussi peut-être réfléchir sur les algorithmes pour ne pas avoir à gérer simultanément toutes les données.

Pour l'approche bourrin du découpage de fichier, on passe au problème de fichiers à records de taille variable + taille des header + ..., donc si on n'a qu'un truc one-shot pour prétraiter les données, pas la peine de faire de la "rocket science".

  • Partager sur Facebook
  • Partager sur Twitter
Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
9 novembre 2018 à 14:54:19

Salut,

Un fichier de 50 Go ? Est ce qu'il est exploitable ?

Je te prends un exemple, imaginons un logiciel 3D qui contient un objet 3D analytique, je veux le discrétiser en triangles, ou en points. 

Je donne au logiciel un paramètre de discrétisation : plus il est élevé, plus le logiciel me découpera mon modèle en triangles plus fins, ou avec un nuage de points plus serré.

Et théoriquement, rien ne m'empêche de pousser le paramétrage jusqu'à faire des milliards de triangles/points... et des fichiers de 50 Go...

Mais des fichiers qu'aucun des logiciels ne relira. Un résultat inexploitable, un non sens....

Est ce qu'on n'est pas dans ce cas la pour ton exemple ? 

  • Partager sur Facebook
  • Partager sur Twitter

Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

9 novembre 2018 à 15:30:11

Fvirtman a écrit:

Salut,

Un fichier de 50 Go ? Est ce qu'il est exploitable ?

Je te prends un exemple, imaginons un logiciel 3D qui contient un objet 3D analytique, je veux le discrétiser en triangles, ou en points. 

Je donne au logiciel un paramètre de discrétisation : plus il est élevé, plus le logiciel me découpera mon modèle en triangles plus fins, ou avec un nuage de points plus serré.

Et théoriquement, rien ne m'empêche de pousser le paramétrage jusqu'à faire des milliards de triangles/points... et des fichiers de 50 Go...

Mais des fichiers qu'aucun des logiciels ne relira. Un résultat inexploitable, un non sens....

Est ce qu'on n'est pas dans ce cas la pour ton exemple ? 

Cela m'intéresse beaucoup ce que tu dis !

Un use case que je vois et dont je ne connais pas vraiment la solution, je serai super intéressé à avoir des pistes @Fvirtman si tu en as.

Imaginons que j'ai un pointcloud énorme provenant par exemple d'un Lidar https://oceanservice.noaa.gov/facts/lidar.html .

J'aimerais faire un streamer qui va calculer à partir d'un frustum de camera quel partie du fichier charger et affichuer. Je peut charger un frustum plus large que mon point de vue pour bufferiser par exemple. Ou comme tu le décris et comme on le fait souvent en tesselation, un paramètre de discrétisation.

Mon problème c'est plutôt comment définir quel chunk du fichier aller charger ? Un fichier comme le format décrit par l'OP est structuré spatialement ? Est-ce que c'est de ça dont tu parler quand tu dis "exploitable" ? Peut-on imaginer une passe de pré-processing du fichier que l'on fait qu'une seule fois ? 

  • Partager sur Facebook
  • Partager sur Twitter
9 novembre 2018 à 15:44:03

Salut !

Il me semble qu'on ne parle pas de la même chose mais tu lances un débat intéressant.

Moi je parlais par exemple, dans un logiciel de CAO, tu fais un cylindre... un simple cylindre. Mathématiquement, c'est parfaitement rond.

Si tu veux l'exporter en un format tessellé, donc une approximation du cylindre fait en triangles, tu va définir un paramètre de tessellation.

Si tu es radin, tu peux te dire, "allez, on va mettre un paramètre de telle sorte mon cylindre soit finalement approximé en une extrusion d'octogone (un cylindre est l'extrusion d'un cercle). Donc tu auras 8 faces rectangulaires, chacune faite de 2 triangles, donc une approximation grossière de 16 triangles.

Si tu veux quelque chose de plus fin, tu va approximer le cercle et faire donc une tessellation plus fine. si tu coupes ton cercle en, allez, 50 morceaux, tu auras déjà un beau cylindre parfaitement approximé.

Mais rien ne t'empêche de couper le cercle en 1000, 1 million, 1 milliard, pour approximer le cercle et faire un fichier tessellé de plusieurs Go. Un simple cylindre de 50 Go .... Et ça, c'est stupide, inutile,  et inexploitable.

Et c'est la personne qui a entré le paramétrage en amont au moment de la sauvegarde qui a fait n'importe quoi.

Evidemment, le cylindre est le cas le plus simple, mais même avec une pièce plus complexe, avoir des fichiers de 50 Go, n'est ce pas avoir clairement abusé ? Bref.

Sinon, ce dont tu parles est intéressant, il concernerait un monde immense, donc forcément fait de beaucoup beaucoup de triangles, et la, il faut avoir structuré le monde. Il existe plein de techniques pour ça, il y a les chunks de voxels comme Minecraft, le BSP comme Quake et pas mal de FPS, et l'octree un peu moins complexe que le BSP mais diablement puissant aussi !

Mais l'idée est déjà que le fichier d'entrée ne soit pas fait n'importe comment. 

  • Partager sur Facebook
  • Partager sur Twitter

Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

9 novembre 2018 à 16:26:30

Tout à fait, mais l'octree est un structure de donnée qui finalement te permet d'indexer l'espace. Mais cela implique d'avoir un octree de construit quelque part. Du coup je me demandais si il y avait des format de fichier déjà structuré et meme avec une API qui permet de se ballader spatialement dans le fichier.
  • Partager sur Facebook
  • Partager sur Twitter
9 novembre 2018 à 16:43:02

On pourrais envisager de stocker l'octree directement dans le fichier :

Le fichier serait ainsi séparé en 8 blocs, quand on charge le fichier, au lieu de charger tout le fichier, on charge l'offset et la taille du bloc. Et quand on veut parcourir une branche, chaque bloc est a nouveau recoupé en 8 blocs, récursivement.

Donc en mémoire, au lieu de tout avoir, on a des branches "non chargées" qui contiennent uniquement l'offset et la taille de la zone d'en dessous si on veut la charger.

Toute la difficulté revient à savoir quand charger un bloc, jusqu'où, et surtout lequel décharger si on commence à avoir la mémoire bien remplie :)

Et sinon en ce qui concerne les BSP, dans les bons vieux FPS d'antan, les fichiers étaient déjà structurés en BSP : on chargeait directement le BSP ! (mais on chargeait tout)...

  • Partager sur Facebook
  • Partager sur Twitter

Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

9 novembre 2018 à 17:05:05

Du coup tu connais des formats de fichiers existants ? Avec une API maybe, ce serait cool de pas avoir à réinventer la roue :-)
  • Partager sur Facebook
  • Partager sur Twitter
9 novembre 2018 à 17:56:02

Je n'en connais pas. Il me semble que les fichiers de Quake 3 c'était assez open, mais c'est peut être un peu vieux maintenant.

(moi j'aime réinventer les roues, pour justement les faire rouler pile comme je le veux, j'adore tout ce qui est bas niveau)

  • Partager sur Facebook
  • Partager sur Twitter

Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

9 novembre 2018 à 23:18:05

On m'a volé ma question :( 

Je précise que c'est des nuages de points et pas des fichiers CAO, hein ! Pas question de triangles ici, mais bien juste de points (d'où le poids des fichiers.. ) 

Mais non ! Alors je suis sur téléphone et je peux pas répondre à tout, ça serai trop long. Mais là librairie libe57 ne permet pas (à mon sens, et c'est pour cela que je pose la question) de lire par chunck ! Mais j'aimerai en être sûr.

Pour ce qui est de la taille des fichiers, on travaille avec des logiciels qui permettent d'ouvrir ces gros fichiers, mais qui ne sont que peu efficaces sur les filtres de nuage de points. En appliquant mes filtres perso, je réduis la taille des fichiers par un facteur 5/10, ce qui est vraiment utile pour la suite.

Bref, non, je ne crée pas des fichiers inexploitable, et ce que je pensais faire, si je pouvais lire par chunck est de créer un octree de fichier (le temps de calcul importe assez peu finalement, d'abord un truc qui marche, ensuite on verra pour optimiser) , ou je stocke mes points dans des fichiers, et puis je travail sur chaque fichier séparer. 

Et si je demandais si il était possible de changer la taille du swap en script, c'est que y'a pas que 1 ordi qui va exploiter ce programme,, mais plusieurs sont destinés, alors j'ai pas envie de devoir modifier tous les ordis. Ducoup si je peux le faire en script  je le mets plus grand au début, puis je le redescend à la fin

Voila voilà 

  • Partager sur Facebook
  • Partager sur Twitter

« Je n’ai pas besoin de preuve. Les lois de la nature, contrairement aux lois de la grammaire, ne permettent aucune exception. »
D. Mendeleïev

9 novembre 2018 à 23:39:17

Du coup, je me demande, est ce que tes fichiers, c'est juste une liste de points en vrac ? (et donc des milliards ?)

Ils sont ordonnés ou alors peuvent arriver dans n'importe quel ordre ? 

Je ne sais plus si c'est toi qui parlait il y a quelques semaines d'un format de fichier assez simple a lire (celui la ?) est ce que le fichier est simple à lire ? Car manifestement, ta lib ne permet pas de lire qu'une partie des données, donc si c'est pas trop dur, réinvente la roue pour rouler à un endroit qui n'est pas prévu ! (donc charge pas paquets)

EDIT : Et si c'était toi, j'ai retrouvé ton intervention. 

Du coup, ton fichier était d'un format très simple à priori ! Avais tu essayé la méthode dont je parle ici ?

https://openclassrooms.com/forum/sujet/lire-un-gros-fichier-de-nuage-de-points-rapidement#message-92702338


EDIT 2 : Et après, tous ces points que veux tu en faire ? Les dessiner à la volée ?

-
Edité par Fvirtman 9 novembre 2018 à 23:43:18

  • Partager sur Facebook
  • Partager sur Twitter

Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

12 novembre 2018 à 8:19:58

En fait, entre temps j'ai eu une demande pour changer de format de fichier. Avant j'utilisais un fichier PTX, c'est un fichier dans lesquels les points sont tous écrit en brut dans un fichier texte. L'ordre n'avait une espece d'importance pour certains logiciels mais pas pour moi.


La on me demande d'utiliser des fichiers e57 qui est un format un peu plus compliqué, et il faut utiliser la libe57 pour pouvoir les utiliser  (enfin, c'est une grande aide).
Il va peut-être falloir que je réinvente la roue pour essayé de charger par bloc, chose que je n'ai pas l'impression qu'il est possible de faire actuellement :(  Mais je sais même pas si c'est possible de le faire en réalité. Je pense que oui, mais le seul logiciel que j'ai vu qui arrive à ouvrir de si gros fichiers de points est celui qu'on utilise dans mon entreprise, mais je comprends pas comment il fait (Et si je dois moi aussi pouvoir l'ouvrir, c'est que ce logiciel n'offre des possibilités que très limitée :()

Merci pour vos aides :)

-
Edité par KirbXCoucou 12 novembre 2018 à 8:34:37

  • Partager sur Facebook
  • Partager sur Twitter

« Je n’ai pas besoin de preuve. Les lois de la nature, contrairement aux lois de la grammaire, ne permettent aucune exception. »
D. Mendeleïev

12 novembre 2018 à 8:58:45

Salut,

Tu peux uploader un petit fichier e57 quelque part, pour voir ?

  • Partager sur Facebook
  • Partager sur Twitter

Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

12 novembre 2018 à 9:13:13

T'as pas les sources de cette "libe57" pour modifier légèrement le code, histoire de dévoiler la roue avant d'en construire une autre ?
  • Partager sur Facebook
  • Partager sur Twitter
Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
12 novembre 2018 à 9:24:05

Ici, il y a un exemple de e57.
J'ai les fichiers .cpp et .h de la lib, oui! Mais je t'avoue que je pense pas avoir les capacité pour pouvoir gérer ça dans un temps raisonnable seul actuellement. Je voulais d'abord savoir si quelqu'un avait déjà planché la dessus avant de m'y mettre moi même. Mais il semblerait que je vais y arriver un moment ou l'autre...

EDIT : En fait, je  crois qu'il existe la fonction
void seek (int64_t  recordNumber);
qui à pour description
Set record number of CompressedVectorNode where next read will start.

Parameters:
    [in]recordNumber The index of record in ComressedVectorNode where next read using this CompressedVectorReader will start.
qui ferait le taf je crois, mais le corps de la fonction c'est ça :
void CompressedVectorReaderImpl::seek(uint64_t /*recordNumber*/)
{
    checkImageFileOpen(__FILE__, __LINE__, __FUNCTION__);

    ///!!! implement
    throw E57_EXCEPTION1(E57_ERROR_NOT_IMPLEMENTED);
}
:(


     

-
Edité par KirbXCoucou 12 novembre 2018 à 10:11:25

  • Partager sur Facebook
  • Partager sur Twitter

« Je n’ai pas besoin de preuve. Les lois de la nature, contrairement aux lois de la grammaire, ne permettent aucune exception. »
D. Mendeleïev

12 novembre 2018 à 10:09:34

Salut,

Effet, j'ai regardé ton fichier avec mon éditeur hexa, en effet ce n'est pas trivial !

  • Partager sur Facebook
  • Partager sur Twitter

Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

12 novembre 2018 à 10:28:01

GG @KirbXCoucou, t'as rapidement localiser un "working in progress" dans le projet.

C'est clairement la fonction qu'il te faut pour lire des "records" par tranche. Mais s'il n'a pas été implémenté directement, c'est que l'implémentation n'est pas trivial.

Avant de chercher à scripter l'élargissement du swap, il faut déjà vérifier que la solution fonctionne. Je viens d'apprendre que le type de licence peu influencer la taille maximale de la mémoire virtuelle :

https://blogs.technet.microsoft.com/markrussinovich/2008/07/21/pushing-the-limits-of-windows-physical-memory/

https://blogs.technet.microsoft.com/markrussinovich/2008/11/17/pushing-the-limits-of-windows-virtual-memory/

Une fois vérifié que cela fonctionne correctement au modifiant le swap, ajouter des commandes shell lors de l'installation, c'est pas la fin du monde.

  • Partager sur Facebook
  • Partager sur Twitter
Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
12 novembre 2018 à 10:35:16

Je vais aller lire ça! :) Merci beaucoup! :)
J'ai demandé aux créateurs de la lib (enfin, j'ai ouvert un tiquet), mais le fait que la dernière MaJ date de 2012 me laisse un peu perplexe pour le coup... M'enfin! On verra! :)
Yes! Commande Shell plutôt que directement dans le c++, c'est sûr que ça doit être plus évident! Je vais tester tout ça!
merci beaucoup!
  • Partager sur Facebook
  • Partager sur Twitter

« Je n’ai pas besoin de preuve. Les lois de la nature, contrairement aux lois de la grammaire, ne permettent aucune exception. »
D. Mendeleïev