I have a very strange problem:
My unmanaged third-party library has a class, let's call it Foo
which has a method bar()
which returns an object of type Bar
, like:
Foo* foo = new Foo();
Bar bar = foo -> bar();
Now, this Bar
has a method which is supposed to initially return true
when it is obtained via the above means. In unmanaged code, this works as desired:
Foo* foo = new Foo();
Bar bar = foo -> bar(); // yes, bar() returns the object, not a pointer
bool b = bar.shouldBeTrue(); // b is true
Now, I wrote a managed wrapper for Foo
and Bar
which is very simple:
Managed.h:
namespace Managed {
public ref class ManagedBar {
private:
ThirdParty::Bar* _delegate;
public:
ManagedBar(ThirdParty::Bar* delegate);
~ManagedBar();
bool shouldBeTrue();
};
public ref class ManagedFoo {
private:
ThirdParty::Foo* _delegate;
public:
ManagedFoo();
~ManagedFoo();
ManagedBar^ bar();
};
}
ManagedBar.cpp (includes stripped):
namespace Managed {
ManagedBar::ManagedBar(ThirdParty::Bar* delegate) {
_delegate = delegate;
}
ManagedBar::~ManagedBar() {
delete _delegate;
}
bool ManagedBar::shouldBeTrue() {
return _delegate -> shouldBeTrue();
}
}
ManagedFoo.cpp:
namespace Managed {
ManagedFoo::ManagedFoo() {
_delegate = new ThirdParty::Foo();
}
ManagedFoo::~ManagedFoo() {
delete _delegate;
}
ManagedBar^ ManagedFoo:bar() {
ThirdParty::Bar tpb = delegate -> bar();
//for test/debugging:
bool b = tpb.shouldBeTrue(); // b is true
return gcnew ManagedBar(&tpb);
}
}
Now, when I call this the following in VB.NET (in a Unit test):
Imports Managed
<TestClass()>
Public Class MyTest
<TestMethod()>
Public Sub TestBarReturnsTrue()
Dim f as ManagedFoo = New ManagedFoo()
Dim b as ManagedBar = f.bar()
Assert.IsTrue(b.shouldBeTrue())
End Sub
End Class
But the assert now fails because it is false. When I step into my ManagedBar
, the _delegate -> shouldBeTrue()
is called without any errors. This behaviour is very strange. Could it be that I did something wrong with my wrapping, or do I have to ask the supplier of the third-party DLL for advice?
The problem is in:
tpb is destroyed after the function call. You should allocate tpb on the heap(you will need to manually free it), save it somewhere(as member) or pass it by value to the ManagedBar.
Hope that will help you.