我有一个非常奇怪的问题:
我的非托管第三方库有一个类,我们称之为Foo
它有一个方法bar()
返回一个类型为 Bar
的对象,例如:
Foo* foo = new Foo();
Bar bar = foo -> bar();
现在,这个Bar
有一种方法,当通过上述方法获得它时,它应该最初返回true
。在非托管代码中,这可按预期工作:
Foo* foo = new Foo();
Bar bar = foo -> bar(); // yes, bar() returns the object, not a pointer
bool b = bar.shouldBeTrue(); // b is true
现在,我为 Foo
和 Bar
编写了一个非常简单的托管包装器:
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(包括剥离(:
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);
}
}
现在,当我在 VB.NET(在单元测试中(调用以下内容时:
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
但是这个断言现在失败了,因为它是错误的。当我进入我的ManagedBar
时,_delegate -> shouldBeTrue()
被调用而没有任何错误。这种行为非常奇怪。可能是我的包装做错了什么,还是我必须向第三方 DLL 的供应商寻求建议?
问题出在:
ManagedBar^ ManagedFoo:bar() {
ThirdParty::Bar tpb = delegate -> bar();
//for test/debugging:
bool b = tpb.shouldBeTrue(); // b is true
return gcnew ManagedBar(&tpb);
}
TPB 在函数调用后被销毁。您应该在堆上分配 tpb(您需要手动释放它(,将其保存在某个地方(作为成员(或按值将其传递给 ManagedBar。
希望对您有所帮助。