作者:专业STB | 来源:互联网 | 2023-09-23 03:44
Dll里用new申请的内存,以指针形式返回给主程序,可以这样用吗,怎么释放,何时释放?做了个小程序,我把dll里申请的mem在主程序里释放,总是出错,什么原因?能给点例子吗?
Dll里用 new 申请的内存,以指针形式返回给主程序,可以这样用吗,怎么释放,何时释放?
做了个小程序,我把dll里申请的mem在主程序里释放,总是出错,什么原因?能给点例子吗?
11 个解决方案
Dll里用 new 申请的内存
还是 Dll里释放好。
建议使用HeapAlloc,然后配对HeapFree释放.
代码大体是这样:
第一步:
把下面代码放到一个dll项目里,会生成一个dll,其中有一个函数叫“StrCatTest”
把这个dll名字也改成StrCatTest.dll,主程序要调用这个dll
typedef struct{
long ilDataType;
union{
bool AsBool; //布尔型
char AsChar; //字符型变量
int AsInt; //整数型变量
double AsDouble; //双精度型变量
char* AsString; //字符串型变量
};
}CIValue;
extern "C" _declspec(dllexport) int __stdcall StrCatTest(CIValue* avArr,CIValue*avRtn){
CIValue vv;
AnsiString s;
s = avArr[0].AsString;
s += avArr[1].AsString;
avRtn->AsString = new char[200]; //长度不是问题
strcpy(avRtn->AsString,s.c_str());
avRtn->ilDataType = 7;
return 0;
}
第二步,随便建个项目,窗体上一个按钮,一个单行文本
加些代码,简写如下:
typedef struct{
long DataType;
union{
bool AsBool; //布尔型
char AsChar; //字符型变量
int AsInt; //整数型变量
double AsDouble; //双精度型变量
char* AsString; //字符串型变量
};
}CIValue;
typedef int(*CIDllFunction)(CIValue*,CIValue*);
CIValue StrAppend(CIValue v1,char* ss){
CIValue vv;
AnsiString s;
s = v1.AsString;
s += ss;
vv.DataType = 7; //string
vv.AsString = new char[200]; //字符长度不必深究
strcpy(vv.AsString,s.c_str());
return vv;
}
//========按钮事件的代码如下:
void __fastcall TForm1::Button1Click(TObject *Sender) {
int r;
CIValue *v;
CIValue v2;
//**CIValue v3;
FARPROC lpFarProc;
HINSTANCE liDllHandle;//DLLa模块的句柄
CIDllFunction lpFunc;
v = new CIValue[2];
v[0].DataType = 7;
v[0].AsString = new char[20];
strcpy(v[0].AsString,"ab");
v[1].DataType = 7;
v[1].AsString = new char[20];
strcpy(v[1].AsString,"cd");
liDllHandle = LoadLibrary("StrCatTest.DLL");//装载连接库, 得到该库句柄
lpFarProc = GetProcAddress(liDllHandle,"StrCatTest"); //得到指向函数的指针
lpFunc = (CIDllFunction)lpFarProc;
lpFunc(v,&v2);
delete[] v[0].AsString; //执行了这句,DataType就变了
delete[] v[1].AsString;
FreeLibrary(liDllHandle);
delete[] v;
//**v3 = StrAppend(v2,"ef");
//**Edit1->Text = v3.AsString;
Edit1->Text = v2.AsString;
}
问题来了:
在执行了delete[] v[0].AsString;这行代码之后,v2的DataType就变了。而且在我的程序里,
执行形如StrAppend的函数时,跟踪进去,v1的DataType 也变,但简化程序后,我跟踪发现加了带//**的代码反倒完全正常了,搞不明白.
我不知道哪写错了,也不知道是不是申请内存的事,大家给看看,谢谢了先。
建议在主程序建立对象,分配好内存,然后将对象指针传入DLL中。
偶在一个工程组里编译运行没有出现错误(最后加一句delete[]v2.AsString,使用了CG).
请楼主确定dll和exe的编译方式是否一样,字符对齐选项是否一致...
肯定不行,dll申请的内存必须由dll负责释放,这是因为C运行库有两份的原因
建议楼主去看看windows核心编程
因为DLL和EXE的使用的C++运行时刻库版本可能不一样,所以不建议使用这种做法
你可以使用COM的方法来让DLL执行清除内存的工作。