[問題描述]
延續《 [log book] 解決演算法結果接口介面化的問題 ─ 要改變指標,請用指標的指標(雙重指標)》之後,又遇到了一個問題,由於我的dll是使用VS2015寫的,但機台的子機程式是用VS2008寫的,當我在exe中釋放的時候,就會出問題。
下圖中,要釋放的記憶體空間result是我在exe中宣告出的記憶體空間,作用是接dll中演算法的運算結果的
[解題思路]
讀到zj510大大的博客《跨DLL的内存分配释放问题 Heap corruption》,雖然裡面在探討的議題與我遇到的稍微不一樣,但看到z大所寫到的:「在一个DLL里面分配内存,然后在DLL的调用者EXE那里释放内存。当DLL和EXE里面有一个是使用MT连接CRT的时候就有问题。如果DLL和EXE都使用MD,那么就没有问题。」,我突然想到:「我應該在dll中釋放dll宣告的記憶體」。
[解決方法]
在dll檔的類別及介面(interface)中,多宣告一個方法釋放dll的記憶體空間的方法 ─ releaseResult
介面的宣告如下
#pragma once
#include "HsStruct.h"
typedef void Result;
class HInspectAlgoInterface
{
public:
virtual ~HInspectAlgoInterface() { ; }
virtual bool inspect(ImageParam imgParam, wdb_type *wd, hole_type *md) = 0;
//virtual bool getResult(std::string Type, int *Num, Result **Ret) = 0;
virtual bool getResult(char* Type, int *Num, Result **Ret) = 0;
virtual bool releaseResult(Result **Ret) = 0;
};
releaseResult的定義如下
bool IrrBurCheckAlgo::releaseResult(Result **Ret)
{
try {
if (*Ret){
delete[] * Ret;
*Ret = NULL;
}
return true;
}
catch (std::exception ex) {
return false;
}
}
執行結果如下:
結論:dll new出來的記憶體位置最好由dll自己釋放
不過後來我有發現:若使用的VS 版本一樣,且都是用MD,就不會發生這個問題
下面提供測試版的程式碼:
VS 2015 dll的程式碼:(用MD編譯)
HInspectAlgoInterface.h
#pragma once
#include "HsStruct.h"
typedef void Result;
class HInspectAlgoInterface
{
public:
virtual ~HInspectAlgoInterface() { ; }
virtual bool inspect(ImageParam imgParam, wdb_type *wd, hole_type *md) = 0;
virtual bool getResult(char* Type, int *Num, Result **Ret) = 0;
virtual bool releaseResult(Result **Ret) = 0;
};
HsStruct.h
#ifndef _HSSTRUCT_H_
#define _HSSTRUCT_H_
typedef struct {
long id;
long chip;
long no;
long Left;
long Top;
long width;
long height;
}wdb_type;
typedef struct{
long hole_size;
long hole_x;
long hole_y;
long hole_dx;
long hole_dy;
}hole_type;
typedef struct{
unsigned char *Src;
int Width;
int Height;
} ImageParam;
沒有留言:
張貼留言