我有6个班级的故事:3个托管和3个原生。 3个托管类是ManagedChildA
,ManagedChildB
和ManagedParent
。
ManagedChildA
,ManagedChildB
都继承自ManagedParentA
。
3个本机类是NativeChildA
,NativeChildB
和NativeParent
。
NativeChildA
,NativeChildB
都继承自NativeParentA
。
此外,ManagedChildA
包裹NativeChildB
,ManagedChildB
包裹ManagedChildB
和ManagedParentA
包裹NativeParentA
。
现在这个故事发生了错误:
ManagedParentA有一个名为ManagedExecute()的方法,它包装了NativeParentA的NativeExecute()。调用此方法时,一切都顺利进行。
NativeChildB,ManagedChildB覆盖ManagedExecute()以提供自己的实现,ManagedChildA :: ManagedExecute()包装NativeChildA :: NativeExecute()和ManagedChildB :: ManagedExecute()包装NativeChildB :: NativeExecute()。
例如,当调用ManagedChildA的重写ManagedExecute()时,尽管出现System.AccessViolation错误,仍会调用NativeChildA :: NativeExecute()。也就是说,无法找到指向NativeChildA原始父级的指针。
我猜指针已从其原始地址移开。我在互联网上阅读,我必须指针防止垃圾收集器(GC)移动内存,但我不知道要固定什么,因为异常会在本机级别抛出。任何有用的提示?
示例:
//C++ -native classes
class NativeFoo
{
public:
NativeFoo(): tested(true){}
virtual void execute()
{
std::cout << "Native Foo" << std::endl;
}
protected:
bool tested;
};
class NativeBarA :NativeFoo
{
public:
NativeBarA(): NativeFoo(){}
void execute()
{
std::cout << "Native Bar A" << std::endl;
}
};
class NativeBarB : public NativeFoo
{
public:
NativeBarB() :NativeFoo(){}
void execute()
{
std::cout << "Native Bar B" << std::endl;
}
};
//CLI interface
public interface class IExecutable
{
public:
Execute();
}
//C++-CLI classes
public ref class ManagedFoo: public IExecutable
{
private:
NativeFoo* impl;
public:
ManagedFoo(): impl(NULL)
{
impl = new NativeFoo();
}
void __clrcall Execute()
{
impl->execute();
}
};
public ref class ManagedBarA: public ManagedFoo
{
private:
NativeBarA* impl;
public:
ManagedBarA(): ManagedFoo(), impl(NULL)
{
impl = new NativeBarA();
}
void __clrcall Execute() override
{
impl->execute();
}
};
public ref class ManagedBarB: public ManagedFoo
{
private:
NativeBarB* impl;
public:
ManagedBarB(): ManagedFoo(), impl(NULL)
{
impl = new NativeBarB();
}
void __clrcall Execute() override
{
impl->execute();
}
};
//Calling code
[STAThread]
static void Main()
{
ManagedFoo^ mfoo = gcnew ManagedFoo();
ManagedBarA mbarA = gcnew ManagedBarA();
ManagedBarB mbarB = gcnew ManagedBarB();
mfoo->Execute(); //OK
mbarA->Execute(); //Error. Debugger sees value of tested as false
mBarB->Execute(); //Error
}
答案 0 :(得分:1)
该代码段的质量非常低,但却充斥着无法编译的代码。一旦我解决了所有错误,就没有责任了。
#include "stdafx.h"
#include <iostream>
using namespace System;
//C++ -native classes
class NativeFoo
{
public:
NativeFoo(): tested(true){}
virtual void execute()
{
std::cout << "Native Foo" << std::endl;
}
protected:
bool tested;
};
class NativeBarA :NativeFoo
{
public:
NativeBarA(): NativeFoo(){}
void execute()
{
std::cout << "Native Bar A" << std::endl;
}
};
class NativeBarB : public NativeFoo
{
public:
NativeBarB() :NativeFoo(){}
void execute()
{
std::cout << "Native Bar B" << std::endl;
}
};
//CLI interface
public interface class IExecutable
{
public:
void Execute();
};
//C++-CLI classes
public ref class ManagedFoo: public IExecutable
{
private:
NativeFoo* impl;
public:
ManagedFoo(): impl(NULL)
{
impl = new NativeFoo();
}
virtual void Execute()
{
impl->execute();
}
};
public ref class ManagedBarA: public ManagedFoo
{
private:
NativeBarA* impl;
public:
ManagedBarA(): ManagedFoo(), impl(NULL)
{
impl = new NativeBarA();
}
virtual void __clrcall Execute() override
{
impl->execute();
}
};
public ref class ManagedBarB: public ManagedFoo
{
private:
NativeBarB* impl;
public:
ManagedBarB(): ManagedFoo(), impl(NULL)
{
impl = new NativeBarB();
}
virtual void __clrcall Execute() override
{
impl->execute();
}
};
//Calling code
[STAThread]
int main(array<System::String ^> ^args)
{
ManagedFoo^ mfoo = gcnew ManagedFoo();
ManagedBarA^ mbarA = gcnew ManagedBarA();
ManagedBarB^ mbarB = gcnew ManagedBarB();
mfoo->Execute(); //OK
mbarA->Execute(); //Fine
mbarB->Execute(); //Fine
}