peut on exporter une structure définie dans une DLL?
4 réponses
giova
plus précisement j'ai définie une structure dans ma dll, et déclaré un
tableau de cette structure. Tout ceci n'est pas exporté car je ne veux
pas que l'on puisse modifier le contenu de l'exterieur.
je veux donc exporter une fonction qui :
1) alloue dynamiquement dans le tableau une "instance" de cette
structure (malloc)
2) qui retourne l'adresse de ce tableau.
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Arnaud Debaene
giova wrote:
plus précisement j'ai définie une structure dans ma dll, et déclaré un tableau de cette structure. Tout ceci n'est pas exporté car je ne veux pas que l'on puisse modifier le contenu de l'exterieur.
je veux donc exporter une fonction qui : 1) alloue dynamiquement dans le tableau une "instance" de cette structure (malloc) 2) qui retourne l'adresse de ce tableau.
mais le compilateur semble ne pas apprecier que je retourne un poiteur de type test puisqu'il me dit ceci :
warning C4518: '__declspec(dllexport ) ' : classe de stockage ou spécificateur(s) de type inattendu(es) ; ignoré(es)
Le declspec doit être avant le type de retour de la fonction (avant le "declarator" pour être précis) : extern "C" __declspec(dllexport) test* WINAPI Test(void); (Ont a généralement tendance à remplacer _stdcall par WINAPI pour facilier le portage à d'autres compilos - au fait ca n'a rien d'obligatoire d'exporter des fonctions en stdcall).
Cependant, ta solution laisse "test" accessible au code client.
du coup je me demande si c'est possible ou si c'est moi qui m'y prends mal.
Plusieurs solutions :
- Le client a besoin de savoir ce qu'est un "test" (pour appeler une méthode dessus, etc...). Dans ce cas test doit être déclarée et définie dans le code client (dans le header). C'est ce que tu fais actuellement.
- Tu te contentes de faire une "forward déclaration" de test. Dans ce cas, to client peut manipuler des test* mais pas les déréférencer et accêder à ces données membres. /* solution macro "standard" pour avoir un seul header pour la DLL et le client qui l'utilise - compiler la DLL en définissant MADLLEXORT */ #ifdef MA_DLL #define MADLLEXORT __declspec(dllexport) _stdcall #else #define MADLLEXORT __declspec(dllimport) _stdcall
extern struct test; //forward declartion de la classe test* MADLLEXORT Test(void);
- Si tu veux que ta structure soit vraiment opaque, tu retournes un "handle" (en fait un void*) : comme çà, le client ne peut absolument pas manipuler le type des infos retournées. #ifdef MA_DLL #define MADLLEXORT __declspec(dllexport) _stdcall #else #define MADLLEXORT __declspec(dllimport) _stdcall typedef void* myhandle; extern "C" myhandle MADLLEXPORT Test(void);
Arnaud
giova wrote:
plus précisement j'ai définie une structure dans ma dll, et déclaré un
tableau de cette structure. Tout ceci n'est pas exporté car je ne veux
pas que l'on puisse modifier le contenu de l'exterieur.
je veux donc exporter une fonction qui :
1) alloue dynamiquement dans le tableau une "instance" de cette
structure (malloc)
2) qui retourne l'adresse de ce tableau.
mais le compilateur semble ne pas apprecier que je retourne un poiteur
de type test puisqu'il me dit ceci :
warning C4518: '__declspec(dllexport ) ' : classe de stockage ou
spécificateur(s) de type inattendu(es) ; ignoré(es)
Le declspec doit être avant le type de retour de la fonction (avant le
"declarator" pour être précis) :
extern "C" __declspec(dllexport) test* WINAPI Test(void);
(Ont a généralement tendance à remplacer _stdcall par WINAPI pour facilier
le portage à d'autres compilos - au fait ca n'a rien d'obligatoire
d'exporter des fonctions en stdcall).
Cependant, ta solution laisse "test" accessible au code client.
du coup je me demande si c'est possible ou si c'est moi qui m'y
prends mal.
Plusieurs solutions :
- Le client a besoin de savoir ce qu'est un "test" (pour appeler une méthode
dessus, etc...). Dans ce cas test doit être déclarée et définie dans le code
client (dans le header). C'est ce que tu fais actuellement.
- Tu te contentes de faire une "forward déclaration" de test. Dans ce cas,
to client peut manipuler des test* mais pas les déréférencer et accêder à
ces données membres.
/*
solution macro "standard" pour avoir un seul header pour la DLL et le client
qui l'utilise - compiler la DLL en définissant MADLLEXORT
*/
#ifdef MA_DLL
#define MADLLEXORT __declspec(dllexport) _stdcall
#else
#define MADLLEXORT __declspec(dllimport) _stdcall
extern struct test; //forward declartion de la classe
test* MADLLEXORT Test(void);
- Si tu veux que ta structure soit vraiment opaque, tu retournes un "handle"
(en fait un void*) : comme çà, le client ne peut absolument pas manipuler le
type des infos retournées.
#ifdef MA_DLL
#define MADLLEXORT __declspec(dllexport) _stdcall
#else
#define MADLLEXORT __declspec(dllimport) _stdcall
typedef void* myhandle;
extern "C" myhandle MADLLEXPORT Test(void);
plus précisement j'ai définie une structure dans ma dll, et déclaré un tableau de cette structure. Tout ceci n'est pas exporté car je ne veux pas que l'on puisse modifier le contenu de l'exterieur.
je veux donc exporter une fonction qui : 1) alloue dynamiquement dans le tableau une "instance" de cette structure (malloc) 2) qui retourne l'adresse de ce tableau.
mais le compilateur semble ne pas apprecier que je retourne un poiteur de type test puisqu'il me dit ceci :
warning C4518: '__declspec(dllexport ) ' : classe de stockage ou spécificateur(s) de type inattendu(es) ; ignoré(es)
Le declspec doit être avant le type de retour de la fonction (avant le "declarator" pour être précis) : extern "C" __declspec(dllexport) test* WINAPI Test(void); (Ont a généralement tendance à remplacer _stdcall par WINAPI pour facilier le portage à d'autres compilos - au fait ca n'a rien d'obligatoire d'exporter des fonctions en stdcall).
Cependant, ta solution laisse "test" accessible au code client.
du coup je me demande si c'est possible ou si c'est moi qui m'y prends mal.
Plusieurs solutions :
- Le client a besoin de savoir ce qu'est un "test" (pour appeler une méthode dessus, etc...). Dans ce cas test doit être déclarée et définie dans le code client (dans le header). C'est ce que tu fais actuellement.
- Tu te contentes de faire une "forward déclaration" de test. Dans ce cas, to client peut manipuler des test* mais pas les déréférencer et accêder à ces données membres. /* solution macro "standard" pour avoir un seul header pour la DLL et le client qui l'utilise - compiler la DLL en définissant MADLLEXORT */ #ifdef MA_DLL #define MADLLEXORT __declspec(dllexport) _stdcall #else #define MADLLEXORT __declspec(dllimport) _stdcall
extern struct test; //forward declartion de la classe test* MADLLEXORT Test(void);
- Si tu veux que ta structure soit vraiment opaque, tu retournes un "handle" (en fait un void*) : comme çà, le client ne peut absolument pas manipuler le type des infos retournées. #ifdef MA_DLL #define MADLLEXORT __declspec(dllexport) _stdcall #else #define MADLLEXORT __declspec(dllimport) _stdcall typedef void* myhandle; extern "C" myhandle MADLLEXPORT Test(void);
mais le compilateur semble ne pas apprecier que je retourne un poiteur de type test puisqu'il me dit ceci :
warning C4518: '__declspec(dllexport ) ' : classe de stockage ou spécificateur(s) de type inattendu(es) ; ignoré(es)
Je ne m'y connais pas en DLL, mais il y a un problème en C : le type test n'est pas défini.
Soit tu définis le type test de la façon suivante : typedef struct { char* nom; int nombre; } test;
Soit ta fonction ne retourne pas test* mais struct test* : extern "C" struct test* __declspec(dllexport) _stdcall Test(void);
En espérant que ça t'aidera.
HalfWolf
giova
Merci Arnaud.
BOn je n'ai pas tout compris (normal , je débute), mais en tout cas le fait de mettre Le declspec avant le type de retour de la fonction , fait que ca fontionne parfaitement.
merci encore.
Arnaud Debaene wrote:
giova wrote:
plus précisement j'ai définie une structure dans ma dll, et déclaré un tableau de cette structure. Tout ceci n'est pas exporté car je ne veux pas que l'on puisse modifier le contenu de l'exterieur.
je veux donc exporter une fonction qui : 1) alloue dynamiquement dans le tableau une "instance" de cette structure (malloc) 2) qui retourne l'adresse de ce tableau.
mais le compilateur semble ne pas apprecier que je retourne un poiteur de type test puisqu'il me dit ceci :
warning C4518: '__declspec(dllexport ) ' : classe de stockage ou spécificateur(s) de type inattendu(es) ; ignoré(es)
Le declspec doit être avant le type de retour de la fonction (avant le "declarator" pour être précis) : extern "C" __declspec(dllexport) test* WINAPI Test(void); (Ont a généralement tendance à remplacer _stdcall par WINAPI pour facilier le portage à d'autres compilos - au fait ca n'a rien d'obligatoire d'exporter des fonctions en stdcall).
Cependant, ta solution laisse "test" accessible au code client.
du coup je me demande si c'est possible ou si c'est moi qui m'y prends mal.
Plusieurs solutions :
- Le client a besoin de savoir ce qu'est un "test" (pour appeler une méthode dessus, etc...). Dans ce cas test doit être déclarée et définie dans le code client (dans le header). C'est ce que tu fais actuellement.
- Tu te contentes de faire une "forward déclaration" de test. Dans ce cas, to client peut manipuler des test* mais pas les déréférencer et accêder à ces données membres. /* solution macro "standard" pour avoir un seul header pour la DLL et le client qui l'utilise - compiler la DLL en définissant MADLLEXORT */ #ifdef MA_DLL #define MADLLEXORT __declspec(dllexport) _stdcall #else #define MADLLEXORT __declspec(dllimport) _stdcall
extern struct test; //forward declartion de la classe test* MADLLEXORT Test(void);
- Si tu veux que ta structure soit vraiment opaque, tu retournes un "handle" (en fait un void*) : comme çà, le client ne peut absolument pas manipuler le type des infos retournées. #ifdef MA_DLL #define MADLLEXORT __declspec(dllexport) _stdcall #else #define MADLLEXORT __declspec(dllimport) _stdcall typedef void* myhandle; extern "C" myhandle MADLLEXPORT Test(void);
Arnaud
Merci Arnaud.
BOn je n'ai pas tout compris (normal , je débute), mais en tout cas le
fait de mettre Le declspec avant le type de retour de la fonction , fait
que ca fontionne parfaitement.
merci encore.
Arnaud Debaene wrote:
giova wrote:
plus précisement j'ai définie une structure dans ma dll, et déclaré un
tableau de cette structure. Tout ceci n'est pas exporté car je ne veux
pas que l'on puisse modifier le contenu de l'exterieur.
je veux donc exporter une fonction qui :
1) alloue dynamiquement dans le tableau une "instance" de cette
structure (malloc)
2) qui retourne l'adresse de ce tableau.
mais le compilateur semble ne pas apprecier que je retourne un poiteur
de type test puisqu'il me dit ceci :
warning C4518: '__declspec(dllexport ) ' : classe de stockage ou
spécificateur(s) de type inattendu(es) ; ignoré(es)
Le declspec doit être avant le type de retour de la fonction (avant le
"declarator" pour être précis) :
extern "C" __declspec(dllexport) test* WINAPI Test(void);
(Ont a généralement tendance à remplacer _stdcall par WINAPI pour facilier
le portage à d'autres compilos - au fait ca n'a rien d'obligatoire
d'exporter des fonctions en stdcall).
Cependant, ta solution laisse "test" accessible au code client.
du coup je me demande si c'est possible ou si c'est moi qui m'y
prends mal.
Plusieurs solutions :
- Le client a besoin de savoir ce qu'est un "test" (pour appeler une méthode
dessus, etc...). Dans ce cas test doit être déclarée et définie dans le code
client (dans le header). C'est ce que tu fais actuellement.
- Tu te contentes de faire une "forward déclaration" de test. Dans ce cas,
to client peut manipuler des test* mais pas les déréférencer et accêder à
ces données membres.
/*
solution macro "standard" pour avoir un seul header pour la DLL et le client
qui l'utilise - compiler la DLL en définissant MADLLEXORT
*/
#ifdef MA_DLL
#define MADLLEXORT __declspec(dllexport) _stdcall
#else
#define MADLLEXORT __declspec(dllimport) _stdcall
extern struct test; //forward declartion de la classe
test* MADLLEXORT Test(void);
- Si tu veux que ta structure soit vraiment opaque, tu retournes un "handle"
(en fait un void*) : comme çà, le client ne peut absolument pas manipuler le
type des infos retournées.
#ifdef MA_DLL
#define MADLLEXORT __declspec(dllexport) _stdcall
#else
#define MADLLEXORT __declspec(dllimport) _stdcall
typedef void* myhandle;
extern "C" myhandle MADLLEXPORT Test(void);
BOn je n'ai pas tout compris (normal , je débute), mais en tout cas le fait de mettre Le declspec avant le type de retour de la fonction , fait que ca fontionne parfaitement.
merci encore.
Arnaud Debaene wrote:
giova wrote:
plus précisement j'ai définie une structure dans ma dll, et déclaré un tableau de cette structure. Tout ceci n'est pas exporté car je ne veux pas que l'on puisse modifier le contenu de l'exterieur.
je veux donc exporter une fonction qui : 1) alloue dynamiquement dans le tableau une "instance" de cette structure (malloc) 2) qui retourne l'adresse de ce tableau.
mais le compilateur semble ne pas apprecier que je retourne un poiteur de type test puisqu'il me dit ceci :
warning C4518: '__declspec(dllexport ) ' : classe de stockage ou spécificateur(s) de type inattendu(es) ; ignoré(es)
Le declspec doit être avant le type de retour de la fonction (avant le "declarator" pour être précis) : extern "C" __declspec(dllexport) test* WINAPI Test(void); (Ont a généralement tendance à remplacer _stdcall par WINAPI pour facilier le portage à d'autres compilos - au fait ca n'a rien d'obligatoire d'exporter des fonctions en stdcall).
Cependant, ta solution laisse "test" accessible au code client.
du coup je me demande si c'est possible ou si c'est moi qui m'y prends mal.
Plusieurs solutions :
- Le client a besoin de savoir ce qu'est un "test" (pour appeler une méthode dessus, etc...). Dans ce cas test doit être déclarée et définie dans le code client (dans le header). C'est ce que tu fais actuellement.
- Tu te contentes de faire une "forward déclaration" de test. Dans ce cas, to client peut manipuler des test* mais pas les déréférencer et accêder à ces données membres. /* solution macro "standard" pour avoir un seul header pour la DLL et le client qui l'utilise - compiler la DLL en définissant MADLLEXORT */ #ifdef MA_DLL #define MADLLEXORT __declspec(dllexport) _stdcall #else #define MADLLEXORT __declspec(dllimport) _stdcall
extern struct test; //forward declartion de la classe test* MADLLEXORT Test(void);
- Si tu veux que ta structure soit vraiment opaque, tu retournes un "handle" (en fait un void*) : comme çà, le client ne peut absolument pas manipuler le type des infos retournées. #ifdef MA_DLL #define MADLLEXORT __declspec(dllexport) _stdcall #else #define MADLLEXORT __declspec(dllimport) _stdcall typedef void* myhandle; extern "C" myhandle MADLLEXPORT Test(void);
Arnaud
giova
et bien en fait je fait une "instance" de la structure en global dans le cpp de ma dll, et ma fonction sort l'adresse de ce dernier, ce qui fait que dans mon main je fais un :
struct test toto; toto=Test();
;)
biensur j'ai egallement fait une fonction qui libere la mémoire par la suite.
mais le compilateur semble ne pas apprecier que je retourne un poiteur de type test puisqu'il me dit ceci :
warning C4518: '__declspec(dllexport ) ' : classe de stockage ou spécificateur(s) de type inattendu(es) ; ignoré(es)
Je ne m'y connais pas en DLL, mais il y a un problème en C : le type test n'est pas défini.
Soit tu définis le type test de la façon suivante : typedef struct { char* nom; int nombre; } test;
Soit ta fonction ne retourne pas test* mais struct test* : extern "C" struct test* __declspec(dllexport) _stdcall Test(void);
En espérant que ça t'aidera.
HalfWolf
et bien en fait je fait une "instance" de la structure en global dans le
cpp de ma dll, et ma fonction sort l'adresse de ce dernier, ce qui fait
que dans mon main je fais un :
struct test toto;
toto=Test();
;)
biensur j'ai egallement fait une fonction qui libere la mémoire par la
suite.
HalfWolf wrote:
Salut,
giova <pas@de.mail> wrote in message news:<408d843c$0$19487$636a15ce@news.free.fr>...
et bien en fait je fait une "instance" de la structure en global dans le cpp de ma dll, et ma fonction sort l'adresse de ce dernier, ce qui fait que dans mon main je fais un :
struct test toto; toto=Test();
;)
biensur j'ai egallement fait une fonction qui libere la mémoire par la suite.