2009-07-29 5 views
0

j'ai une classe, A, en C++/CLI qui dérive d'une classe de base basé sur un modèle, B. J'ai un code C# qui a une instance de A et veut appeler une méthode dessus. Si la méthode est implémentée dans A tout va bien. S'il est implémenté dans B les choses deviennent étranges.appel d'une méthode de C# sur une base sur matrice C++/CLI classe

Je frappai le code le plus simple qui montre ce que je suis en train de faire:

C++/CLI:

 
template<typename T> 
public ref class B 
{ 
public: 
    void Test(){} 
};

public ref class A : public B<System::Int32> { };

C#:

 
    A a = new A(); 
    a.Test(); 

Dans ce code de test, l'appel à Test() ne compile pas (j'obtiens: "ne contient pas de définition pour 'Test'"). J'obtiens le même résultat si je le modifie pour rendre Test() statique (et l'appeler au A, plutôt que l'instance). Si c'était la fin de l'histoire je voudrais juste serrer mon poing chez Microsoft et vivre avec.

Cependant, dans mon vrai code j'ai mon équivalent à Test() de travail! Bizarrement, cela ne fonctionne que dans un cas. Si je copie ma méthode de travail et que je change juste le nom, la nouvelle méthode est à nouveau inaccessible.

Pour exclure la désignation étant pris d'ailleurs j'ai essayé d'enlever la méthode de travail. Le code ne parvient pas à générer, comme prévu.

Je suppose que ce que je vois, encore, est un pépin et que ce que j'essaie de faire n'est pas supporté. Mais comme je ne trouve pas de références qui l'excluent, et avec l'anomalie que je vois, j'aimerais savoir avec certitude ce que je devrais attendre.

Répondre

2

En langage C++ simple, les méthodes de classe basée sur un modèle ne sont instanciées que si elles sont réellement utilisées dans la portée de liaison. Je soupçonne que l'implémentation C++/CLI peut faire l'équivalent - ne générant pas de code pour Test() si elle n'est pas utilisée dans l'assembly C++.

+0

C'est pourquoi j'aime stackoverflow :-) C'est * exactement * ce qui se passe. Si évident quand on y pense. Je peux y travailler maintenant. Merci pour votre réponse rapide. – philsquared

-1

La réponse à votre question est vraiment très simple. Lorsque vous compilez votre assemblage mixte - C++/CLI, il existe certaines règles que le compilateur suit pour exporter des fonctions natives en dehors de l'assemblage et produire des métadonnées à leur place. L'un d'entre eux est que les méthodes natives ne sont pas exposées à l'extérieur de l'assemblage sauf si elles sont explicitement spécifiées. Pour spécifier explicitement une méthode native à exposer via des métadonnées, utilisez le #pragma make_public(Your Class Here). L'autre est que les fonctions du modèle ne peuvent pas être exposées à l'extérieur de l'assemblage. Donc, dans votre cas, vous ne pouvez pas exposer la classe de modèle. MAIS dans votre cas, je suis presque certain que vous n'avez pas besoin de classe de modèle, mais un générique qui est tout à fait OK pour être exporté.

Pourquoi avez-vous besoin de modèles? Comprenez-vous la différence entre le modèle <> et le générique <>? L'un est l'unité de temps de compilation, l'autre est l'exécution.

Essayez d'utiliser

generic<class T> 
public ref class B 
{ 
public: 
    void Test(){} 
}; 


public ref class A : public B<System::Int32> 
{ 
}; 
+0

Il n'y a pas de méthodes natives dans son code. Les deux classes sont 'ref', donc tout le code est géré. –

+0

Merci pour vos commentaires, Ivan. Évidemment, l'exemple n'est pas représentatif de ce que j'essaie de faire avec les modèles. J'utilise un modèle ici spécifiquement pour obtenir des résultats de compilation. Je ne peux pas réaliser la même chose avec les génériques. Il semble que la réponse acceptée était tout ce dont j'avais besoin pour que cela fonctionne. – philsquared

Questions connexes