我想我需要更清楚地描述我的问题:
被调用的dll将仅在堆上管理其内存。呼唤 部分是在堆栈上管理它的内存。呼叫部分没有 访问dll内存分配信息。所以,当我打电话给 解构函数如“~UserVideoAbstration”。它不能释放 在堆上分配的内存。
这是与* .dll内部实现相关的问题
我正在做一个项目,有2个部分,一个是将密钥算法实现打包到* .dll文件中。我将算法部分封装到对象实现中。
class UserVideoAbstraction{
private:
VideoAbstraction *userVB;
public:
__declspec(dllexport) UserVideoAbstraction(const char* inputpath, const char* videoname, const char* midname);
__declspec(dllexport) UserVideoAbstraction();
__declspec(dllexport) ~UserVideoAbstraction();
__declspec(dllexport) void UserAbstraction(Mat& currentFrame, int frameIndex); //进行背景减除的函数
__declspec(dllexport) int UsersaveConfigInfo();
在构造函数中,我这样写:
UserVideoAbstraction::UserVideoAbstraction(const char* inputpath, const char* videoname,const char* midname)
{
string t1=inputpath;
string t2=videoname;
string t3=midname;
userVB =new VideoAbstraction(t1,t2,t3);
}
所以你知道,当我调用* .dll时,它会分配内存。调用部分是项目的第二部分,它是基于.Net的windows实现,但我在第二部分找到,
提供这样的解构功能
是没用的
UserVideoAbstraction::~UserVideoAbstraction(){
delete userVB;
};
所以我想知道你是否有一个很好的解决方案来解决这个问题。
应用程序实现部分介绍......
这是正常的C ++实现,调用部分是一个带有C ++的控件按钮实现(.Net)。
就像那样:
//initial part
UserVideoAbstraction use(inputpath, videoname, midname);
//deconstruct part
use.~UserVideoAbstration();
答案 0 :(得分:0)
你应该打电话不要手动调用析构函数。
UserVideoAbstraction::~UserVideoAbstraction(){
delete userVB;
};
但是,最好使用std::tr1::shared_ptr<VideoAbstraction>
而不是原始指针,然后您不必手动删除它。 (您可以在std::shared_ptr<>
)
C++11
或者根本没有使用[{1}}类型userVB
的指针:
VideoAbstraction
答案 1 :(得分:0)
我只是显式定义了一个函数,它执行与解构函数类似的任务来释放对象的内存,分配的内存被成功释放。
这是我的解决方案,第一部分是
void VideoAbstraction::freeObject(){
videoCapture.~VideoCapture();
videoWriter.~VideoWriter();
backgroundImage.release();
currentStartIndex.release();
currentEndIndex.release();
mog.~BackgroundSubtractorMOG2();
.............
}
封装部分像那样重新设计
__declspec(dllexport) void UserfreeObject();// declaration part
//implementation part
void UserVideoAbstraction::UserfreeObject(){
userVB->freeObject();
}
答案 2 :(得分:0)
从评论看来,您认为问题是由于.NET垃圾收集器没有确定性地删除dll中的C ++对象。这是错的。虽然.NET将使用其构造函数创建对象,但最终将调用析构函数。最终。此时,.NET代码将执行相同的过程,因为调用将发生释放对象使用的内存 - 在此套接字中,该调用将是对象析构函数。
规则很简单:在C ++类中封装所有内容,在构造函数中分配的内容,在解构器中释放。
如果您正在编写C ++ / CLI类,那么您可能希望使用析构函数的endiser语法(叹气,Microsoft ..为什么)uses the ! symbol在类名之前(例如{{} 1}})。如果您正在使用P / Invoke样式互操作,那么现在就停止它,它无论如何都与C ++对象不兼容,并且woudl是你的析构函数没有被自动调用的原因 - 尽管我猜你可以在下面对析构函数进行显式调用你的处置或终结者。