OVH Cloud OVH Cloud

Interop C++ Natif et Environnement Managé

5 réponses
Avatar
Laurent Testud
Bonjour,

Je suis auteur d'une librairie ou plutot d'une sorte de framework utile
pour le developpement de jeu sous DirectX ( SxDL sur SourceForge.net si
ca vous interresse ) que je voudrais pouvoir utiliser en C# et tous les
autres managed languages. Le framework est integralement écrit en C++
natif et fonctionne un peu à la manière des MFC : L'application herite
d'une classe de base applicative et on override des methodes virtuelles
pour y ajouter de la fonctionnalité.

Comment m'y prendre ? Un lien qq part pour me mettre sur la ( bonne )
voie ?

PS : La solution doit etre performante. ( == rapide dans ce cas )

PPS : Cela fait deja quatre ans que je fais du dot net et je n'ai encore
jamais ete confronté a ce genre de probleme, P/Invoke avait jusqu'à
present toujours fait l'affaire.

Merci

Laurent Testud at Dashing Pixels dot com

5 réponses

Avatar
Laurent Testud
Précision : Le machin fait environ 40,000 lignes de code C++ et je
cherche aussi à faire en sorte de limiter le plus possible l'effort
d'interfaçage.

Thx

Laurent Testud at Dashing Pixels dot com
Avatar
Simon Mourier
Difficile de répondre rapidement à cette question :-)

Il n'est pas possible d'avoir une "translation" directe entre héritage C++
et héritage .NET. En gros, les possibilités dont on dispose sont donc:

1) Exposer votre framework sous formes de fonctions (et non plus de classes)
permettant l'utilisation de DllImport à vos clients. D'un point de vue
client, l'intégration n'est pas extraordinaire, et cela vous oblige à
rajouter une couche très procédurale à votre framework objet.

2) COM import, mais vous n'avez pas d'objets COM je pense.

3) Créer une assembly .NET C++ managé qui utilise vos classes C++
directement, et qui offre donc à vos clients l'interface .NET que vous
souhaitez. Il y a eu énormément d'amélioration au C++ managé dans le
Framework 2.0 (on ne parle plus de Managed C++ mais de C++/CLI). A votre
place, je commencerai par là: http://msdn.microsoft.com/visualc/whidbey/

Simon Mourier
www.softfluent.com

"Laurent Testud" a écrit
dans le message de news: %
Bonjour,

Je suis auteur d'une librairie ou plutot d'une sorte de framework utile
pour le developpement de jeu sous DirectX ( SxDL sur SourceForge.net si ca
vous interresse ) que je voudrais pouvoir utiliser en C# et tous les
autres managed languages. Le framework est integralement écrit en C++
natif et fonctionne un peu à la manière des MFC : L'application herite
d'une classe de base applicative et on override des methodes virtuelles
pour y ajouter de la fonctionnalité.

Comment m'y prendre ? Un lien qq part pour me mettre sur la ( bonne ) voie
?

PS : La solution doit etre performante. ( == rapide dans ce cas )

PPS : Cela fait deja quatre ans que je fais du dot net et je n'ai encore
jamais ete confronté a ce genre de probleme, P/Invoke avait jusqu'à
present toujours fait l'affaire.

Merci

Laurent Testud at Dashing Pixels dot com


Avatar
David Alloza
Bonjour Laurent,
Il me semble que la meilleure approche serait d'utiliser une assembly en
C++ manage afin de wrapper tes classes. Tes classes seront alors
accessibles depuis n'importe quel langage managé.
Une classe managée ne pouvant hériter d'une classe non managée, il
faudra que tu mette en place un modèle à base d'encapsulation et non
d'heritage dans ton wrapper. En gros, il faudrait que tes classes de
wrap managées encapsulent des pointeurs vers des object de ton
framework, et que les virtuals de tes objects de base soient appelés
depuis les virtuals de tes classes managées de wrapp.
Aini, tu pourrait profiter de l'héritage dans une hierarchie de classes
managées.
Pour la performance, ça te rajoute une indirection.
De plus, je te conseille de mettre ton framework dans une DLL win32, et
d'utiliser cette DLL depuis ton assembly en C++ Manage, tu aura ainsi
beaucoup moins de problèmes d'object globaux ou classes statiques non
initialisées que si tu fesait un link direct d'une librairie statique win32.
David.
( developpeur de jeux vidéos depuis 7 ans, developpeur occasionnel .NET
depuis 2 ans ).




Laurent Testud wrote:
Bonjour,

Je suis auteur d'une librairie ou plutot d'une sorte de framework utile
pour le developpement de jeu sous DirectX ( SxDL sur SourceForge.net si
ca vous interresse ) que je voudrais pouvoir utiliser en C# et tous les
autres managed languages. Le framework est integralement écrit en C++
natif et fonctionne un peu à la manière des MFC : L'application herite
d'une classe de base applicative et on override des methodes virtuelles
pour y ajouter de la fonctionnalité.

Comment m'y prendre ? Un lien qq part pour me mettre sur la ( bonne )
voie ?

PS : La solution doit etre performante. ( == rapide dans ce cas )

PPS : Cela fait deja quatre ans que je fais du dot net et je n'ai encore
jamais ete confronté a ce genre de probleme, P/Invoke avait jusqu'à
present toujours fait l'affaire.

Merci

Laurent Testud at Dashing Pixels dot com


Avatar
Sylvain Lafontaine
Je quote: « L'application herite d'une classe de base applicative et on
override des methodes virtuelles pour y ajouter de la fonctionnalité. »

Vous voulez en somme que des classes C# (ou VB.NET ou autre) puissent
hériter directement de vos classes C++ ?

Malheureusement, cela ne fait pas trop orienté object; puisqu'une librairie
indépendante devrait être autonome dans ses besoins. Sans vouloir m'engager
ici dans une discussion sans fin, j'ai bien l'impression qu'à force de
vouloir la performance ultime - comme si cela pouvait avoir un sens réel ou
pratique - vous vous êtes piégé vous-même dans un cul-de-sac évolutif.

--
Sylvain Lafontaine, ing.
MVP - Technologies Virtual-PC


"Laurent Testud" wrote in
message news:%
Bonjour,

Je suis auteur d'une librairie ou plutot d'une sorte de framework utile
pour le developpement de jeu sous DirectX ( SxDL sur SourceForge.net si ca
vous interresse ) que je voudrais pouvoir utiliser en C# et tous les
autres managed languages. Le framework est integralement écrit en C++
natif et fonctionne un peu à la manière des MFC : L'application herite
d'une classe de base applicative et on override des methodes virtuelles
pour y ajouter de la fonctionnalité.

Comment m'y prendre ? Un lien qq part pour me mettre sur la ( bonne ) voie
?

PS : La solution doit etre performante. ( == rapide dans ce cas )

PPS : Cela fait deja quatre ans que je fais du dot net et je n'ai encore
jamais ete confronté a ce genre de probleme, P/Invoke avait jusqu'à
present toujours fait l'affaire.

Merci

Laurent Testud at Dashing Pixels dot com


Avatar
Remi Thomas - MVP
"Laurent Testud"
Bonjour,

Je suis auteur d'une librairie ou plutot d'une sorte de framework utile
pour le developpement de jeu sous DirectX ( SxDL sur SourceForge.net si ca
vous interresse ) que je voudrais pouvoir utiliser en C# et tous les
autres managed languages. Le framework est integralement écrit en C++
natif et fonctionne un peu à la manière des MFC : L'application herite
d'une classe de base applicative et on override des methodes virtuelles
pour y ajouter de la fonctionnalité.

Comment m'y prendre ? Un lien qq part pour me mettre sur la ( bonne ) voie
?

PS : La solution doit etre performante. ( == rapide dans ce cas )

PPS : Cela fait deja quatre ans que je fais du dot net et je n'ai encore
jamais ete confronté a ce genre de probleme, P/Invoke avait jusqu'à
present toujours fait l'affaire.




Salut Laurent,

C'est possible à condition de ne pas utiliser l'héritage multiple dans ton
code C++ que tu désires wrapper.
La bonne question à se poser est : comment appeler une méthode de base d'une
classe dérivée si je n'ai jamais instancié cette classe de base?
Tu peux t'en sortir avec une macro pour mettre en place un mécanisme de
pointeur sur la classe instancié.

#define NOGCCLASSWRAPPER(ContainerClassName,NestedClassType,Init,Id)
private:
NestedClassType *m_ptr;
void ConstructorTrace() { /* Console::WriteLine("Constructor
"#NestedClassType); */ }
void New() { if (GetId()==Id) { ConstructorTrace(); m_ptr = __nogc new
NestedClassType;} else m_ptr=0; }
public:
ContainerClassName() { New(); Init(); }
virtual ~ContainerClassName() { if (m_ptr!=0) { /*
Console::WriteLine("Destructor "#NestedClassType); */ delete m_ptr;} }
virtual void*_GetNestedPtr() { return m_ptr; }
virtual int GetId() { return Id; }
NestedClassType *GetNestedPtr() { return static_cast<NestedClassType
*>(_GetNestedPtr()); }

/*
exemple

C++

class baseType
{
int m_type;
public:
baseType() { SetType(5); }
int GetType() { return m_type; }
void SetType(int type) { m_type=type; }
};

class derivedType : public baseType
{
public:
derivedType() { SetType(6); }
int Add(int a, int b) { return a+b; }
};

C++/CLI (ou managed C++)
namespace LNNetWrapper2
{
class baseType
{
NOGCCLASSWRAPPER(baseType, ::baseType, __noop);
public:
int GetType() { return GetNestedPtr()->GetType(); }
};

class derivedType : public baseType
{
NOGCCLASSWRAPPER(derivedType, ::derivedType, __noop);
public:
int Add(int a, int b) {return GetNestedPtr()->Add(a,b);}
};
}
*/

J'avais dans l'idée d'écrire un article sur le sujet mais pour le moment je
n'ai pas trop le temps.
Bien entendu les méthodes virtuelles et le polymorphisme fonctionnent avec
ce mécanisme.
Il parait qu'un White Paper existe sur ce point mais je ne l'ai jamais
trouvé.

Rémi

--
Rémi Thomas - MVP Visual Studio .NET
Développeur Windows indépendant
http://www.xtware.com/cv