2010-11-26 31 views
3

J'ai la structure suivante:Erreur de table virtuelle C++?

//Unmanaged(.h) 
class myInterface 
{ 
public: 
    virtual bool Send(char* myChar); 
} 

//Managed (.h) 
class myClass; 

public ref class Parser 
{ 
    bool Transmit(String^ mString); 
} 

class myClass : public myInterface 
{ 
public: 
    virtual bool Send(char* myChar); 
private: 
    gcroot<Parser^> pParser; 
} 

Mon problème est que quelque part dans mon code non géré, je dois appeler la fonction Envoyer. Il appelle la fonction à partir du code Managed Send, mais la fonction Send appelle la méthode Transmit à partir de la classe Parser. Le problème est que lorsque je débogue, l'instance de pParser est vide (même si je l'avais déjà instancié auparavant dans le constructeur).

Est-ce un problème de récupérateur de place ou une table virtuelle induite en erreur? Comment puis-je le réparer? Merci!

MISE À JOUR: Après un nouvel Debugging, je me suis rendu compte que si j'inclus d'autres instances de gcroot par exemple:

gcroot<AppDomaion^> pDomain;

et puis, dans le code, a essayé de courir:

pDomain = AppDomain::CurrentDomain;

le Debugger montrerait la même valeur vide que pour le pParser. Y at-il quelque chose qui ne va pas avec ce que je fais? devrais-je instancier la classe d'une manière différente?

MAJ2:

Le Managed/Unmanaged ressemble à ceci:

Wrapper: (wrapper.h)

public ref class Wrapper 
{ 
public: 
    Send(String^ mSendMessage); 
    Parse(String^ mMessageString); 
... 
private: 
    ComLayer* mComm; 
    CInferface mInterface; 
}; 

private class CInterface : public IIterface 
{ 
public: 
    virtual bool Deliver(CMessage mMessage); 
... 
private: 
    gcroot<Wrapper^> mParent; 
}; 

Wrapper (wrapper.cpp)

Wrapper::Send(String^ mSendMessage) 
{ 
... 
mComm->Send(mMessage); 
} 
Wrapper::Parse(String^ mMessageString) 
{ 
... 
} 

CInterface::Deliver(CMessage* mMessage) 
{ 
... 
//Here, mParent value is empty under Labview, not while Debug/VS/WindowsForm 
mParent->Parse(mMessageString) 
} 

Non géré: (commLayer.h)

class CommLayer 
{ 
public: 
//Send: 
    bool Send(CMessage* mMessage); 
... 
private: 
//instead of CInterface, IInterface. 
    IInterface mInterface; 
}; 

Unmanaged: (IInterface.h)

class IInterface 
{ 
public: 
//Response: 
    virtual bool Deliver(CMessage mMessage); 
}; 

Le problème est que lorsque le code non managé appelle le mInferface-> Livrer (mMessage); Il n'y a pas d'instance pour mParent. Ensuite, dans le Wrapper, mParent est vide (value = null); Est comme il accèderait seulement aux méthodes à partir de la IInterface non gérée et non du Wrapper^à partir de l'encapsuleur CInterface.

+0

Ce n'est pas standard C++; S'il vous plaît pourriez-vous l'étiqueter avec quelque chose de plus spécifique? –

+0

Avez-vous activé le débogage non géré dans Visual Studio? Dans les options de débogage pour le projet exécutable, il existe un paramètre pour "Activer le débogage de code non géré". – Nick

+0

@Oli Charlesworth: Merci la glace. @Nick.J'appelle la bibliothèque gérée depuis Labview et après 'attacher le processus', je débogue le code. Devrais-je encore activer le débogage de code non managé? Que devrais-je chercher? –

Répondre

0

Je crois que vous devez activer à la fois le débogage natif et le débogage géré lors de la connexion au processus.

Vous pouvez le faire dans la boîte de dialogue Attacher au processus en cliquant sur le bouton "Sélectionner" à côté de la case "Joindre à:".

Bien que cela soit généralement défini sur "Automatique", ce qui devrait déterminer si un processus est en cours d'exécution avec le CLR et sélectionner les entrées correctes pour ce dialogue.

+0

Je reçois toujours une instance vide. Je pense que mon problème est plus lié à AppDomains qu'avec Virtual Tables ou Garbage Collector. J'essaye toujours de comprendre comment appeler tout dans un seul AppDomain ou au moins permettre aux différents AppDomains de partager une classe. –

+0

Pendant le débogage sur VisualStudio, le ManagedCode & UnmanagedCode s'exécute dans un AppDomain ConsoleTest.vshost.exe, tandis que dans Labview, le ManagedCode s'exécute dans un "Labview Domain for Run" tandis que le UnmanagedCode s'exécute dans un "Default Domain" –

+0

Ainsi, dans votre L'application ConsoleTest ne vous pose aucun problème, mais lorsque vous l'exécutez dans LabView, vous voyez les valeurs vides? Avez-vous une chance de joindre plus de code? – Nick