Note that there are some explanatory texts on larger screens.

plurals
  1. POCalling overridden method of derived native class through wrappers (derived Managed Classes) in C++/CLI
    primarykey
    data
    text
    <p>I have a tale of 6 classes: 3 managed and 3 native.</p> <p>The 3 managed classes are ManagedChildA, ManagedChildB and ManagedParent. </p> <p>ManagedChildA, ManagedChildB both inherit from ManagedParentA.</p> <p>The 3 nativeclasses are NativeChildA, NativeChildB and NativeParent. </p> <p>NativeChildA, NativeChildB both inherit from NativeParentA.</p> <p>Moreover, ManagedChildA wraps NativeChildB, ManagedChildB wraps ManagedChildB and ManagedParentA wraps NativeParentA. </p> <p>Now here the tale gows awry:</p> <p>ManagedParentA has a method called ManagedExecute() that wraps NativeParentA's NativeExecute(). When this method is called, everything runs smoothly.</p> <p>NativeChildB, ManagedChildB override ManagedExecute() to provide their own implementations, with ManagedChildA::ManagedExecute() wrapping NativeChildA::NativeExecute() and ManagedChildB::ManagedExecute() wrapping NativeChildB::NativeExecute().</p> <p>When for example the overriden ManagedExecute() of ManagedChildA is called, NativeChildA::NativeExecute() gets called albeit with a System.AccessViolation error. That is, the pointer to the original parent of NativeChildA cannot be located. </p> <p>I guess the pointer has been moved from its original address. I read on the internet, I have to pin pointers to prevent the Garbage Collector (GC) from moving memory around but I don't know what to pin, since the exception gets thrown at the native level. Any useful hints? </p> <p>Example:</p> <pre class="lang-cpp prettyprint-override"><code>//C++ -native classes class NativeFoo { public: NativeFoo(): tested(true){} virtual void execute() { std::cout &lt;&lt; "Native Foo" &lt;&lt; std::endl; } protected: bool tested; }; class NativeBarA :NativeFoo { public: NativeBarA(): NativeFoo(){} void execute() { std::cout &lt;&lt; "Native Bar A" &lt;&lt; std::endl; } }; class NativeBarB : public NativeFoo { public: NativeBarB() :NativeFoo(){} void execute() { std::cout &lt;&lt; "Native Bar B" &lt;&lt; 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-&gt;execute(); } }; public ref class ManagedBarA: public ManagedFoo { private: NativeBarA* impl; public: ManagedBarA(): ManagedFoo(), impl(NULL) { impl = new NativeBarA(); } void __clrcall Execute() override { impl-&gt;execute(); } }; public ref class ManagedBarB: public ManagedFoo { private: NativeBarB* impl; public: ManagedBarB(): ManagedFoo(), impl(NULL) { impl = new NativeBarB(); } void __clrcall Execute() override { impl-&gt;execute(); } }; //Calling code [STAThread] static void Main() { ManagedFoo^ mfoo = gcnew ManagedFoo(); ManagedBarA mbarA = gcnew ManagedBarA(); ManagedBarB mbarB = gcnew ManagedBarB(); mfoo-&gt;Execute(); //OK mbarA-&gt;Execute(); //Error. Debugger sees value of tested as false mBarB-&gt;Execute(); //Error } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload