Je souhaites construire une dll avec MinGW sous windows et utiliser
cette dll sous visual C++.
(car la librairie que je souhaites compiler ne se compile pas sous VC++)
Est-ce possible ? Si oui, quelqu'un aurait-il des infos à me donner ?
Y-a-t-il des exemples de type "hello world" ?
Bonjour, C'est plutot un probleme de programmation Windows que de C++ (voir fr.comp.os.ms-windows.programmation).
Je souhaites construire une dll avec MinGW sous windows et utiliser cette dll sous visual C++.
Regarde comment utiliser __declspec( dllimport ) et __declspec( dllexport ).
Pour MinGW, je ne sais pas trop mais avec cygwin il n'y a tout simplement rien à faire pour de l'export/import implicite de symbole.
Voir par exemple : http://groups-beta.google.com/group/fr.comp.lang.c++/browse_thread/thread/a6c528f2010b54c0
kanze
Olivier Azeau wrote:
Aurélien REGAT-BARREL wrote:
C'est plutot un probleme de programmation Windows que de C++ (voir fr.comp.os.ms-windows.programmation).
Je souhaites construire une dll avec MinGW sous windows et utiliser cette dll sous visual C++.
Regarde comment utiliser __declspec( dllimport ) et __declspec( dllexport ).
Pour MinGW, je ne sais pas trop mais avec cygwin il n'y a tout simplement rien à faire pour de l'export/import implicite de symbole.
Ça dépend un peu de ce qu'il veut faire avec son DLL, non ? S'il veut un chargement implicite au démarrage, ce que tu dis es vrai, mais on se démande bien alors pourquoi il veut un DLL. Si c'est pour implémenter un espèce de plug-in, en revanche, il est en général préferrable que les symboles exportés soient « extern "C" », de façon à pouvoir les spécifier facilement.
Aussi, je ne connais pas bien le modèle Windows de DLL, mais je crois bien qu'il distingue entre les symboles exportés, et ceux qui ne le sont pas. Je crois en plus (mais je ne suis pas sûr) que GetProcAddress ne trouve le symbole que s'il a été exporté. Et puisqu'exporter systèmatiquement tous les symboles n'est pas une solution acceptable, il faut bien un mechanisme lors de la génération de la DLL pour spécifier quels symboles on veut exporter.
Note que le modèle Unix est bien différent, en ce que c'est au moment du chargement qu'on spécifier si les symboles exportés doivent être visible par ailleurs, et que dlsym (l'équivalent plus ou moins de GetProcAddress) trouve un symbole exporté même si on a spécifié que les symboles ne doivent pas être visible par ailleurs. Dans ce modèle, exporter tous les symboles devient une solution acceptable, et c'est en fait ce que font les éditeurs de liens Unix. Mais les solutions valables dans un modèle ne convienent pas forcement à d'autres modèles.
-- James Kanze GABI Software Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Olivier Azeau wrote:
Aurélien REGAT-BARREL wrote:
C'est plutot un probleme de programmation Windows que de C++
(voir fr.comp.os.ms-windows.programmation).
Je souhaites construire une dll avec MinGW sous windows et
utiliser cette dll sous visual C++.
Regarde comment utiliser __declspec( dllimport ) et
__declspec( dllexport ).
Pour MinGW, je ne sais pas trop mais avec cygwin il n'y a tout
simplement rien à faire pour de l'export/import implicite de
symbole.
Ça dépend un peu de ce qu'il veut faire avec son DLL, non ? S'il
veut un chargement implicite au démarrage, ce que tu dis es
vrai, mais on se démande bien alors pourquoi il veut un DLL. Si
c'est pour implémenter un espèce de plug-in, en revanche, il est
en général préferrable que les symboles exportés soient « extern
"C" », de façon à pouvoir les spécifier facilement.
Aussi, je ne connais pas bien le modèle Windows de DLL, mais je
crois bien qu'il distingue entre les symboles exportés, et ceux
qui ne le sont pas. Je crois en plus (mais je ne suis pas sûr)
que GetProcAddress ne trouve le symbole que s'il a été exporté.
Et puisqu'exporter systèmatiquement tous les symboles n'est pas
une solution acceptable, il faut bien un mechanisme lors de la
génération de la DLL pour spécifier quels symboles on veut
exporter.
Note que le modèle Unix est bien différent, en ce que c'est au
moment du chargement qu'on spécifier si les symboles exportés
doivent être visible par ailleurs, et que dlsym (l'équivalent
plus ou moins de GetProcAddress) trouve un symbole exporté même
si on a spécifié que les symboles ne doivent pas être visible
par ailleurs. Dans ce modèle, exporter tous les symboles devient
une solution acceptable, et c'est en fait ce que font les
éditeurs de liens Unix. Mais les solutions valables dans un
modèle ne convienent pas forcement à d'autres modèles.
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
C'est plutot un probleme de programmation Windows que de C++ (voir fr.comp.os.ms-windows.programmation).
Je souhaites construire une dll avec MinGW sous windows et utiliser cette dll sous visual C++.
Regarde comment utiliser __declspec( dllimport ) et __declspec( dllexport ).
Pour MinGW, je ne sais pas trop mais avec cygwin il n'y a tout simplement rien à faire pour de l'export/import implicite de symbole.
Ça dépend un peu de ce qu'il veut faire avec son DLL, non ? S'il veut un chargement implicite au démarrage, ce que tu dis es vrai, mais on se démande bien alors pourquoi il veut un DLL. Si c'est pour implémenter un espèce de plug-in, en revanche, il est en général préferrable que les symboles exportés soient « extern "C" », de façon à pouvoir les spécifier facilement.
Aussi, je ne connais pas bien le modèle Windows de DLL, mais je crois bien qu'il distingue entre les symboles exportés, et ceux qui ne le sont pas. Je crois en plus (mais je ne suis pas sûr) que GetProcAddress ne trouve le symbole que s'il a été exporté. Et puisqu'exporter systèmatiquement tous les symboles n'est pas une solution acceptable, il faut bien un mechanisme lors de la génération de la DLL pour spécifier quels symboles on veut exporter.
Note que le modèle Unix est bien différent, en ce que c'est au moment du chargement qu'on spécifier si les symboles exportés doivent être visible par ailleurs, et que dlsym (l'équivalent plus ou moins de GetProcAddress) trouve un symbole exporté même si on a spécifié que les symboles ne doivent pas être visible par ailleurs. Dans ce modèle, exporter tous les symboles devient une solution acceptable, et c'est en fait ce que font les éditeurs de liens Unix. Mais les solutions valables dans un modèle ne convienent pas forcement à d'autres modèles.
-- James Kanze GABI Software Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
xavier
a dit le 11/03/2005 09:15:
Ça dépend un peu de ce qu'il veut faire avec son DLL, non ? S'il veut un chargement implicite au démarrage, ce que tu dis es vrai, mais on se démande bien alors pourquoi il veut un DLL. Si c'est pour implémenter un espèce de plug-in, en revanche, il est en général préferrable que les symboles exportés soient « extern "C" », de façon à pouvoir les spécifier facilement.
Pas nécessairement. En effet, lors du chargement d'une DLL, le chargeur dynamique de Windows regarde si cette DLL fournie un point d'entrée, et exécute ce point d'entrée dans le cadre du chargement.
Aussi, je ne connais pas bien le modèle Windows de DLL, mais je crois bien qu'il distingue entre les symboles exportés, et ceux qui ne le sont pas.
Oui.
Je crois en plus (mais je ne suis pas sûr) que GetProcAddress ne trouve le symbole que s'il a été exporté.
Oui.
Et puisqu'exporter systèmatiquement tous les symboles n'est pas une solution acceptable, il faut bien un mechanisme lors de la génération de la DLL pour spécifier quels symboles on veut exporter.
Exporter systématiquement tous les symboles peut être une solution acceptable, si le code utilise correctement les namespace anonymes afin de ne pas polluer l'espace global. Note qu'une option de l'éditeur de liens fourni avec MinGW (GNU ld, --export-all-symbols) permet justement de faire cela. Les autres options sont l'utilisation des attributs (__declspec(dllexport) avec VC/ICC et __attribute__((dllexport)) avec GCC) ou l'utilisation d'un fichier '.DEF' contenant la liste des symboles à exporter. Ce dernier cas est cependant quasi inutilisable en C++ car ce sont les noms "manglés" qu'il faut donner à l'éditeur de lien.
Mais dans le cas qui intéresse l'OC, c'est à dire créer une DLL avec GCC pour ensuite l'utiliser avec VC, il est important de noter que cela n'est possible que pour les fonctions et variables déclarées extern "C". L'ABI C++ des deux compilateurs est incompatible.
xavier
kanze@gabi-soft.fr a dit le 11/03/2005 09:15:
Ça dépend un peu de ce qu'il veut faire avec son DLL, non ? S'il
veut un chargement implicite au démarrage, ce que tu dis es
vrai, mais on se démande bien alors pourquoi il veut un DLL. Si
c'est pour implémenter un espèce de plug-in, en revanche, il est
en général préferrable que les symboles exportés soient « extern
"C" », de façon à pouvoir les spécifier facilement.
Pas nécessairement. En effet, lors du chargement d'une DLL, le chargeur
dynamique de Windows regarde si cette DLL fournie un point d'entrée, et
exécute ce point d'entrée dans le cadre du chargement.
Aussi, je ne connais pas bien le modèle Windows de DLL, mais je
crois bien qu'il distingue entre les symboles exportés, et ceux
qui ne le sont pas.
Oui.
Je crois en plus (mais je ne suis pas sûr)
que GetProcAddress ne trouve le symbole que s'il a été exporté.
Oui.
Et puisqu'exporter systèmatiquement tous les symboles n'est pas
une solution acceptable, il faut bien un mechanisme lors de la
génération de la DLL pour spécifier quels symboles on veut
exporter.
Exporter systématiquement tous les symboles peut être une solution
acceptable, si le code utilise correctement les namespace anonymes afin
de ne pas polluer l'espace global. Note qu'une option de l'éditeur de
liens fourni avec MinGW (GNU ld, --export-all-symbols) permet justement
de faire cela. Les autres options sont l'utilisation des attributs
(__declspec(dllexport) avec VC/ICC et __attribute__((dllexport)) avec
GCC) ou l'utilisation d'un fichier '.DEF' contenant la liste des
symboles à exporter. Ce dernier cas est cependant quasi inutilisable en
C++ car ce sont les noms "manglés" qu'il faut donner à l'éditeur de lien.
Mais dans le cas qui intéresse l'OC, c'est à dire créer une DLL avec GCC
pour ensuite l'utiliser avec VC, il est important de noter que cela
n'est possible que pour les fonctions et variables déclarées extern "C".
L'ABI C++ des deux compilateurs est incompatible.
Ça dépend un peu de ce qu'il veut faire avec son DLL, non ? S'il veut un chargement implicite au démarrage, ce que tu dis es vrai, mais on se démande bien alors pourquoi il veut un DLL. Si c'est pour implémenter un espèce de plug-in, en revanche, il est en général préferrable que les symboles exportés soient « extern "C" », de façon à pouvoir les spécifier facilement.
Pas nécessairement. En effet, lors du chargement d'une DLL, le chargeur dynamique de Windows regarde si cette DLL fournie un point d'entrée, et exécute ce point d'entrée dans le cadre du chargement.
Aussi, je ne connais pas bien le modèle Windows de DLL, mais je crois bien qu'il distingue entre les symboles exportés, et ceux qui ne le sont pas.
Oui.
Je crois en plus (mais je ne suis pas sûr) que GetProcAddress ne trouve le symbole que s'il a été exporté.
Oui.
Et puisqu'exporter systèmatiquement tous les symboles n'est pas une solution acceptable, il faut bien un mechanisme lors de la génération de la DLL pour spécifier quels symboles on veut exporter.
Exporter systématiquement tous les symboles peut être une solution acceptable, si le code utilise correctement les namespace anonymes afin de ne pas polluer l'espace global. Note qu'une option de l'éditeur de liens fourni avec MinGW (GNU ld, --export-all-symbols) permet justement de faire cela. Les autres options sont l'utilisation des attributs (__declspec(dllexport) avec VC/ICC et __attribute__((dllexport)) avec GCC) ou l'utilisation d'un fichier '.DEF' contenant la liste des symboles à exporter. Ce dernier cas est cependant quasi inutilisable en C++ car ce sont les noms "manglés" qu'il faut donner à l'éditeur de lien.
Mais dans le cas qui intéresse l'OC, c'est à dire créer une DLL avec GCC pour ensuite l'utiliser avec VC, il est important de noter que cela n'est possible que pour les fonctions et variables déclarées extern "C". L'ABI C++ des deux compilateurs est incompatible.
xavier
Aurélien REGAT-BARREL
Mais dans le cas qui intéresse l'OC, c'est à dire créer une DLL avec GCC pour ensuite l'utiliser avec VC, il est important de noter que cela n'est possible que pour les fonctions et variables déclarées extern "C". L'ABI C++ des deux compilateurs est incompatible.
Qui plus est MingW génère un .a et non un .lib utilisable par VC++. Donc passer par un .def me parrait nécessaire afin de le convertir en .lib pour VC++ avec lib.exe /DEF.
-- Aurélien REGAT-BARREL
Mais dans le cas qui intéresse l'OC, c'est à dire créer une DLL avec
GCC pour ensuite l'utiliser avec VC, il est important de noter que
cela n'est possible que pour les fonctions et variables déclarées
extern "C". L'ABI C++ des deux compilateurs est incompatible.
Qui plus est MingW génère un .a et non un .lib utilisable par VC++.
Donc passer par un .def me parrait nécessaire afin de le convertir en .lib
pour VC++ avec lib.exe /DEF.
Mais dans le cas qui intéresse l'OC, c'est à dire créer une DLL avec GCC pour ensuite l'utiliser avec VC, il est important de noter que cela n'est possible que pour les fonctions et variables déclarées extern "C". L'ABI C++ des deux compilateurs est incompatible.
Qui plus est MingW génère un .a et non un .lib utilisable par VC++. Donc passer par un .def me parrait nécessaire afin de le convertir en .lib pour VC++ avec lib.exe /DEF.
-- Aurélien REGAT-BARREL
James Kanze
xavier wrote:
a dit le 11/03/2005 09:15:
Exporter systématiquement tous les symboles peut être une solution acceptable, si le code utilise correctement les namespace anonymes afin de ne pas polluer l'espace global.
Ce qui suppose que le plug-in s'écrit dans une seule unité de compilation. C'est un contraint draconien, non ?
Note qu'une option de l'éditeur de liens fourni avec MinGW (GNU ld, --export-all-symbols) permet justement de faire cela. Les autres options sont l'utilisation des attributs (__declspec(dllexport) avec VC/ICC et __attribute__((dllexport)) avec GCC) ou l'utilisation d'un fichier '.DEF' contenant la liste des symboles à exporter. Ce dernier cas est cependant quasi inutilisable en C++ car ce sont les noms "manglés" qu'il faut donner à l'éditeur de lien.
En passant, je crois que la solution avec un fichier .DEF marche aussi avec VC++. Avec la même restriction -- il faut donner les noms décorés.
Mais dans le cas qui intéresse l'OC, c'est à dire créer une DLL avec GCC pour ensuite l'utiliser avec VC, il est important de noter que cela n'est possible que pour les fonctions et variables déclarées extern "C". L'ABI C++ des deux compilateurs est incompatible.
En effet. Dans ce cas-là, il faut non seulement que les fonctions qu'on veut appeler soit « extern "C" », il faut qu'il n'y a rien dans l'interface qui n'est pas compatible C -- que des struct POD, par exemple, et pas de classe.
-- James Kanze home: www.gabi-soft.fr Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34
xavier wrote:
kanze@gabi-soft.fr a dit le 11/03/2005 09:15:
Exporter systématiquement tous les symboles peut être une
solution acceptable, si le code utilise correctement les
namespace anonymes afin de ne pas polluer l'espace global.
Ce qui suppose que le plug-in s'écrit dans une seule unité de
compilation. C'est un contraint draconien, non ?
Note qu'une option de l'éditeur de liens fourni avec MinGW
(GNU ld, --export-all-symbols) permet justement de faire cela.
Les autres options sont l'utilisation des attributs
(__declspec(dllexport) avec VC/ICC et
__attribute__((dllexport)) avec GCC) ou l'utilisation d'un
fichier '.DEF' contenant la liste des symboles à exporter. Ce
dernier cas est cependant quasi inutilisable en C++ car ce
sont les noms "manglés" qu'il faut donner à l'éditeur de lien.
En passant, je crois que la solution avec un fichier .DEF marche
aussi avec VC++. Avec la même restriction -- il faut donner les
noms décorés.
Mais dans le cas qui intéresse l'OC, c'est à dire créer une
DLL avec GCC pour ensuite l'utiliser avec VC, il est important
de noter que cela n'est possible que pour les fonctions et
variables déclarées extern "C". L'ABI C++ des deux
compilateurs est incompatible.
En effet. Dans ce cas-là, il faut non seulement que les
fonctions qu'on veut appeler soit « extern "C" », il faut qu'il
n'y a rien dans l'interface qui n'est pas compatible C -- que
des struct POD, par exemple, et pas de classe.
--
James Kanze home: www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34
Exporter systématiquement tous les symboles peut être une solution acceptable, si le code utilise correctement les namespace anonymes afin de ne pas polluer l'espace global.
Ce qui suppose que le plug-in s'écrit dans une seule unité de compilation. C'est un contraint draconien, non ?
Note qu'une option de l'éditeur de liens fourni avec MinGW (GNU ld, --export-all-symbols) permet justement de faire cela. Les autres options sont l'utilisation des attributs (__declspec(dllexport) avec VC/ICC et __attribute__((dllexport)) avec GCC) ou l'utilisation d'un fichier '.DEF' contenant la liste des symboles à exporter. Ce dernier cas est cependant quasi inutilisable en C++ car ce sont les noms "manglés" qu'il faut donner à l'éditeur de lien.
En passant, je crois que la solution avec un fichier .DEF marche aussi avec VC++. Avec la même restriction -- il faut donner les noms décorés.
Mais dans le cas qui intéresse l'OC, c'est à dire créer une DLL avec GCC pour ensuite l'utiliser avec VC, il est important de noter que cela n'est possible que pour les fonctions et variables déclarées extern "C". L'ABI C++ des deux compilateurs est incompatible.
En effet. Dans ce cas-là, il faut non seulement que les fonctions qu'on veut appeler soit « extern "C" », il faut qu'il n'y a rien dans l'interface qui n'est pas compatible C -- que des struct POD, par exemple, et pas de classe.
-- James Kanze home: www.gabi-soft.fr Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34
xavier
James Kanze a dit le 12/03/2005 23:14:
Ce qui suppose que le plug-in s'écrit dans une seule unité de compilation. C'est un contraint draconien, non ?
En fait, non. Exporter un nom interne n'est pas forcément gênant, d'un point de vue pratique, car le système utilise la paire (nom de bibliothèque, nom de fonction) pour déterminer le symbole dont il est fait référence. Il n'y a pas de pollution de la table des symboles à proprement parler, puisque chaque exécutable ou librairie dynamique garde sa table propre.
xavier
James Kanze a dit le 12/03/2005 23:14:
Ce qui suppose que le plug-in s'écrit dans une seule unité de
compilation. C'est un contraint draconien, non ?
En fait, non. Exporter un nom interne n'est pas forcément gênant, d'un
point de vue pratique, car le système utilise la paire (nom de
bibliothèque, nom de fonction) pour déterminer le symbole dont il est
fait référence. Il n'y a pas de pollution de la table des symboles à
proprement parler, puisque chaque exécutable ou librairie dynamique
garde sa table propre.
Ce qui suppose que le plug-in s'écrit dans une seule unité de compilation. C'est un contraint draconien, non ?
En fait, non. Exporter un nom interne n'est pas forcément gênant, d'un point de vue pratique, car le système utilise la paire (nom de bibliothèque, nom de fonction) pour déterminer le symbole dont il est fait référence. Il n'y a pas de pollution de la table des symboles à proprement parler, puisque chaque exécutable ou librairie dynamique garde sa table propre.