【问题标题】:C++ Virtual Table Error?C++ 虚拟表错误?
【发布时间】:2011-05-16 02:05:23
【问题描述】:

我有以下结构:

//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;
}

我的问题是在我的非托管代码的某个地方,我必须调用 Send 函数。它从托管代码 Send 调用函数,但是,Send 函数从 Parser 类调用 Transmit 方法。问题是当我调试时,pParser 实例是空的(即使我之前已经在构造函数中实例化了它)。

这是垃圾收集器问题还是虚拟表误导?我该如何解决? 谢谢!

更新: 经过进一步调试,我意识到如果我包含其他 gcroot 实例,例如:

gcroot&lt;AppDomaion^&gt; pDomain;

然后,在代码中,尝试运行:

pDomain = AppDomain::CurrentDomain;

调试器将显示与 pParser 相同的空值。我在做什么有什么问题吗?我应该以不同的方式实例化该类吗?

更新 2:

托管/非托管是这样的:

包装器:(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.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)
}

非托管:(commLayer.h)

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

非托管:(IInterface.h)

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

问题是当非托管代码调用 mInferface->Deliver(mMessage) ; mParent 没有实例。然后,在 Wrapper 中,mParent 为空(value = null);就像它只会从非托管 IInterface 访问方法,而不是从包装器 CInterface 访问 Wrapper^。

【问题讨论】:

  • 这不是标准的 C++;请问你能用更具体的东西标记它吗?
  • 您是否在 Visual Studio 中打开了非托管调试?在可执行项目的调试选项中有“启用非托管代码调试”的设置。
  • @Oli Charlesworth:谢谢icecrime。 @缺口。我正在从 Labview 调用托管库,在“附加流程”之后,我正在调试代码。我还应该启用非托管代码调试吗?我应该寻找什么?
  • 嗯,我不熟悉 LabView,但是如果您使用 VisualStudio 附加到进程,您仍然应该能够在附加对话框中启用非托管调试。有一个名为“附加到”的选择框,请确保在附加之前选择了 Native 和 Managed。

标签: c++-cli virtual unmanaged managed mixed-mode


【解决方案1】:

我认为附加到进程时需要同时开启 Native 和 Managed 调试。

您可以在“附加到进程”对话框中执行此操作,方法是单击“附加到:”框旁边的“选择”按钮。

虽然通常将其设置为“自动”,这应该确定一个进程是否正在使用 CLR 运行并为此对话框选择正确的条目。

【讨论】:

  • 我仍然得到一个空实例。我认为我的问题更多地与 AppDomains 相关,而不是虚拟表或垃圾收集器。我仍在尝试弄清楚如何在一个 AppDomain 中调用所有内容,或者至少允许不同的 AppDomain 共享一个类。
  • 在 VisualStudio 上调试时,ManagedCode 和 UnmanagedCode 在 ConsoleTest.vshost.exe AppDomain 中运行,而在 Labview 中,ManagedCode 在“Labview Domain for Run”中运行,而 UnmanagedCode 在“Default域”
  • 那么,在您的 ConsoleTest 应用程序中,您没有遇到任何问题,但是当您在 LabView 中运行它时,您会看到空值?您有机会附上更多代码吗?
  • 没错。我复制了一些我已经在这篇文章中发布的代码:stackoverflow.com/questions/4266427/… 尝试使用序列化进行,无法创建具有所有值的构造方法。我在这里错过了一些非常重要的东西吗?我不是程序员,而是有额外任务的电路设计师!感谢您的帮助。
猜你喜欢
  • 2011-01-11
  • 2016-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-28
  • 2019-01-01
相关资源
最近更新 更多