DLL qui permet de lire un fichier .txt

Fermé
Argile92 Messages postés 10 Date d'inscription vendredi 10 août 2007 Statut Membre Dernière intervention 26 novembre 2007 - 14 août 2007 à 16:47
kilian Messages postés 8731 Date d'inscription vendredi 19 septembre 2003 Statut Modérateur Dernière intervention 20 août 2016 - 17 août 2007 à 12:58
Bonjour,

J'ai un problème au niveau du code d'une DLL en C++ qui permet depuis Excel d'accèder à des données se trouvant dans un fichier extérieur .txt.
Le contenu du .txt est de la forme suivante : "03/03/2007 100" -> 1 colonne

J'ai un problème lors du lancement de ma macro Excel, l'erreur est la suivante : "Bad DLL calling convention".

Le code C++ est le suivant:

#include "stdafx.h"
#include <string>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <comdef.h>

using namespace std;

#ifdef _MANAGED
#pragma managed(push, off)
#endif

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
					 )
{
    return TRUE;
}

#ifdef _MANAGED
#pragma managed(pop)
#endif

struct Donnees{
	SAFEARRAY* date;
	SAFEARRAY* prix;
};

int test(SAFEARRAY** Liste){
	
	// Accès au données
	Donnees *donn;
	SafeArrayAccessData(*Liste,(void**)&donn);

	
	// Parcours du ficher .txt pour compter le nombre de ligne
	int taille = 0;
	ifstream file;
	string line;

	file.open("table2.txt");

	if(file.is_open()){	
		// On prend chaque ligne du fichier
		while(getline(file,line))
			taille++;
	
		file.close();
	}
	else {
		return 0;
		exit(0);
	}


	// Initialisation du tableau de données
	SAFEARRAYBOUND rgsabound;
	rgsabound.cElements = taille;
	rgsabound.lLbound = 0;

	SafeArrayRedim(donn[0].date, &rgsabound);
	SafeArrayRedim(donn[0].prix, &rgsabound);


	// Remplissage du tableau de données
	int Index(0);
	string date_f="";			
	string prix_f="";

	file.open("table2.txt");

	if(file.is_open()){
		// Accès aux données des SafeArrays
		SafeArrayLock(donn[0].date);
		SafeArrayLock(donn[0].prix);
		
		double* quo = (double*)(donn[0].prix) -> pvData;
		string* dat = (string*)(donn[0].date) -> pvData;

		// Parcours du fichier
		while(getline(file,line)){
			file >> date_f >> prix_f;
			
			quo[Index] = atof(prix_f.c_str());
			dat[Index] = date_f;

			Index++;
		}
		// Déverrouillage des données
		SafeArrayUnlock(donn[0].date);
		SafeArrayUnlock(donn[0].prix);

		file.close();
	}

	else{
		return 0;
		exit(0);
	}

	
	return 1;
}




Et le code VBA est le suivant :

Declare Function test Lib "C/|Bureau\testdll.dll" (ByRef Liste() As Données)

Public Type Données

    date() As String
    prix() As Double
    
End Type
    
Sub Extraction_des_donnees()
    
    Dim Liste() As Données
    
    Call test(Liste)

End Sub




Que dois-je modifier pour que ma DLL puisse marcher?

Merci de votre aide.

Tchou!!!
A voir également:

5 réponses

kilian Messages postés 8731 Date d'inscription vendredi 19 septembre 2003 Statut Modérateur Dernière intervention 20 août 2016 1 527
14 août 2007 à 16:55
"Bad DLL calling convention"

Sous windows, la convention de passage de paramètre est stdcall.
Mais il y a des chances que par défaut, ton compilateur utilise cdecl.
Voir: programmation conventions de passage de parametres sous x86

L'histoire du APIENTRY utilisé dans dllmain, c'est en fait un synonyme de stdcall (c'est une constante du préprocesseur définie dans les en-têtes de l'api windows).

En gros, il faut que tu remplaces
int test(SAFEARRAY** Liste)

par
int APIENTRY test(SAFEARRAY** Liste)

pour que la fonction test soit compilée en stdcall, et les choses devraient rentrer dans l'ordre.
0
Argile92 Messages postés 10 Date d'inscription vendredi 10 août 2007 Statut Membre Dernière intervention 26 novembre 2007
17 août 2007 à 10:37
Merci pour la modification, maintenant je n'ai plus de problème d'appel.

Néanmoins, une erreur se produit lors du redimensionnement des SafeArrays forçant Excel à fermé.

Le code est le suivant :

#include "stdafx.h"
#include <string>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <comdef.h>

using namespace std;

#ifdef _MANAGED
#pragma managed(push, off)
#endif

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
					 )
{
    return TRUE;
}

#ifdef _MANAGED
#pragma managed(pop)
#endif

struct Donnees{
	SAFEARRAY* date;
	SAFEARRAY* prix;
};

int _stdcall test(SAFEARRAY** Liste){
	
	// Accès au données
	Donnees *donn;
	SafeArrayAccessData(*Liste,(void**)&donn);

	
	// Parcours du ficher .txt pour compter le nombre de ligne	
	int taille = 0;
	ifstream file;
	string line;

	file.open("G:/STAGE/Pierre/testdll/debug/table2.txt");

	if(file.is_open()){	
		// On prend chaque ligne du fichier
		while(getline(file,line))
			taille++;
	
		file.close();
	}
	else {
		return 0;
		exit(0);
	}

	// Structure modele pour le redimensionnement des SafeArrays
	SAFEARRAYBOUND rgsabound;
	rgsabound.cElements = taille;
	rgsabound.lLbound=0;

	SafeArrayRedim(donn[0].date,&rgsabound);
	SafeArrayRedim(donn[0].prix,&rgsabound);


	// Remplissage du tableau de données
	int Index(0);
	string date_f="";			
	string prix_f="";

	file.open("G:/STAGE/Pierre/testdll/debug/table2.txt");

	if(file.is_open()){

		// Accès aux données des SafeArrays
		SafeArrayLock(donn[0].date);
		SafeArrayLock(donn[0].prix);		

		double* quo = (double*)(donn[0].prix) -> pvData;
		string* dat = (string*)(donn[0].date) -> pvData;
		
		// Parcours du fichier
		while(getline(file,line)){
			file >> date_f >> prix_f;
							
			quo[Index] = atof(prix_f.c_str());
			dat[Index] = date_f;

			Index++;
		}
	
		// Déverrouillage des données
		SafeArrayUnlock(donn[0].date);
		SafeArrayUnlock(donn[0].prix);

		file.close();
	}

	else{
		return 0;
		exit(0);
	}
	
	return 1;
}



Et l'erreur survient au niveau de :

	SafeArrayRedim(donn[0].date,&rgsabound);
	SafeArrayRedim(donn[0].prix,&rgsabound);



Que dois-je faire?

Merci ^^
0
kilian Messages postés 8731 Date d'inscription vendredi 19 septembre 2003 Statut Modérateur Dernière intervention 20 août 2016 1 527
17 août 2007 à 10:46
Aucune idée, j'ai jamais touché aux safearrays....
0
Ok c'est bon, je viens de trouver mon erreur : elle se trouvant dans le code VBA.

Le programme tourne, sauf qu'il ne rentre pas dans la boucle suivante :

// Parcours du fichier
		while(getline(file,line)){
			file >> date_f >> prix_f;

			quo[Index] = atof(prix_f.c_str());
			dat[Index] = date_f;

			Index++;
		}


lorsque j'ouvre et je parcours pour la seconde fois mon fichier .txt

Pourquoi ne puis-je pas reparcourir mon fichier?

Merci
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
kilian Messages postés 8731 Date d'inscription vendredi 19 septembre 2003 Statut Modérateur Dernière intervention 20 août 2016 1 527
17 août 2007 à 12:58
Aucune idée :-/
0