我在dll中有个返回list的函数,但是在释放dll的时候出错(100分)

  • 主题发起人 主题发起人 盛利
  • 开始时间 开始时间

盛利

Unregistered / Unconfirmed
GUEST, unregistred user!
dll中
function titlelist(body: string): TList;
begin
titlelist := TList.Create;
titlelist.free;
------------------------这个需要不
end;
调用dll
iLibHandle := LoadLibrary(Pchar(pluginname));
tmpnewslist := tlist.Create;
if iLibHandle <> 0 then
begin
try
newslist := GetProcAddress(iLibHandle, 'titlelist');
tmpnewslist := newslist(strbody);
MyInfo := tmpnewslist.Items;

finally
tmpnewslist.Free;
// FreeLibrary(iLibHandle);---------------------------这里释放dll,一用就出错
end;

 
释放
之后newaliat没法交待了,当然出错,dll这样用不行
 
我在dll中不用 titlelist.free;
还是出错啊!
 
呵呵,你不要使用TList作为动态库返回的值,使用其他的。如果要传递回来指针数组,那么可以作为参数来完成。
如:
function titlelist(body: string): TList;
改为:
procedure titlelist(body: string;aList:TList):
记住一个原子:对于程序调用,在那里创建,就要在那里释放,不要在主程序中调用,在动态库中释放,更不要在动态库中建立,传递给主程序。
还有,不要将释放了的东西传递给主程序,这样一定出问题。
 
谢谢yzhshi,
还有一个问题请教
function content(body: string): pchar;是我在dll里返回一个pchar
var
tmpstr:string;
begin
Result:= pchar(tmpstr);
end;
但是如果tmpstr的内容太长,在主程序就会内存访问错误,怎么解决啊!
 
同样道理啊
>>function content(body: string): pchar;
procedure content(body: string;a_retrun:pchar);
这样由主程序建立空间,主程序释放空间,不会出问题的。
 
还有在procedure titlelist(body: string;aList:TList):
里怎么用alist啊!
 
》procedure titlelist(body: string;aList:TList):
主程序中:
var
l_List: TList;
begin
l_List:=TList.Create;//主程序创建StringList
titleList(body,l_list);//调用动态库
... //对结果进行处理
l_list.Free;
//释放TList
end;
不过最好不要用String作为参数以及返回类型。
procedure titlelist(body: string;aList:TList):
~~~~~~~~~~~~
 
我是说在dll里直接用alist吗?
 
procedure titlelist(body: string;aList:TList):
begin
aList.Clear;
AList.Add(....)
end;

主程序中
for i:=0 to aList.Count-1 do
begin

aList访问。
end;
 
在 procedure titlelist(body: string;aList:TList): 里面(aList应该是先创建了的)
可以用aList.add添加所有项,也可以用aList.Assign赋值
 
不行啊
总是出错!
 
你的那个String类型去掉了没?
 
我改成pchar了
还是不行 啊
一运行dll内的访问错误
谢谢yzhshi,


**************已经解决
谢谢pipi
还有一个问题请教
function content(body: string): pchar;是我在dll里返回一个pchar
var
tmpstr:string;
begin
Result:= pchar(tmpstr);
end;
但是如果tmpstr的内容太长,在主程序就会内存访问错误,怎么解决啊!
 
var
tmpstr:string;
放到外面去,作为全局变量,不要作为局部变量
 
另外 一运行dll内的访问错误 ,最好放出全部代码,才知道你怎么做的
 
dll全部代码
unit PlugInUnit;
interface
uses Graphics, extdlgs, Windows, Classes, SysUtils;
type
TnewsInfo = record
title: string;
url: string;
newstime: Tdatetime;
content: string;
end;

function groupname: pchar;
//新闻类别名称
function groupurl: pchar;
//新闻地址
//function titlelist(body: string): TList;
//新闻标题列表
procedure titlelist(body: pchar;aList:bList);
//新闻标题列表
function content(body: string): pchar;
//新闻内容
function Html2Text(Str: string): string;
//html2text
implementation
function groupname: pchar;
//新闻类别名称
begin
Result := pchar('网易国内新闻');
end;

function groupurl: pchar;
//新闻地址
begin
Result := pchar('http://news.163.com/local.html');
end;

function Html2Text(Str: string): string;
var
StrL, i: Integer;
NewStr: string;
begin
StrL := StrLen(PChar(Str));
i := 0;
while i < StrL do
begin
Inc(i);
if Str = '>' then
begin
while Str[i + 1] <> '<' do
begin
Inc(i);
if i > StrL then
Break;
NewStr := NewStr + Str;
end;
//End While
end;
//End if
end;
//end While
Result := NewStr;
end;

//function titlelist(body: string): TList;
//新闻标题列表
procedure titlelist(body: pchar;aList:TList);
var
strtemp: string;
substr: string;
urlstr, urltemp: string;
title, temptitle, temptime: string;
newstime: Tdatetime;
MyInfo: ^TnewsInfo;
begin
//titlelist := TList.Create;
strtemp := StrPas(body);
while pos('<li>', strtemp) <> 0 do
begin
strtemp := copy(strtemp, pos('<li>', strtemp) + 4, length(strtemp) - pos('<li>', strtemp) - 4);
substr := copy(strtemp, 1, pos('</font>', strtemp) + 7);
//取出新闻内容页地址
if pos('href=', substr) <> 0 then
begin
urltemp := copy(substr, pos('href=', substr) + 5, length(substr) - pos('href=', substr) - 5);
urlstr := 'http://news.163.com' + copy(urltemp, 1, pos('target=_blank>', urltemp) - 2);
end;
//标题
title := Html2Text('<>' + substr);
title := StringReplace(title, '"', '', [rfReplaceAll]);
title := StringReplace(title, ')', ')', [rfReplaceAll]);
title := StringReplace(title, '(', '(', [rfReplaceAll]);
//时间 (07-15 13:38) --》2002-07-15 13:38
//取最好一对括号里的内容
temptitle := title;
while pos('(', temptitle) <> 0 do
begin
temptime := copy(temptitle, pos('(', temptitle) + 1, pos(')', temptitle) - pos('(', temptitle) - 1);
temptitle := copy(temptitle, pos(')', temptitle) + 1, length(temptitle) - pos(')', temptitle));
end;
try
newstime := strtodatetime(temptime);
except
newstime := now;
end;
if (title <> '') then
begin
New(MyInfo);
MyInfo^.title := title;
MyInfo^.url := urlstr;
MyInfo^.newstime := newstime;
alist.Add(MyInfo);
end;
end;
end;

function content(body: string): pchar;
//新闻内容
var
content: string;
begin
content := copy(body, pos('<!--start_1-->', body) + 14, pos('<!--end_1-->', body) - pos('<!--start_1-->', body) - 14);
if pos('<!--start_img-->', body) <> 0 then
content := '<center>' + copy(body, pos('<!--start_img-->', body) + 16, pos('<!--end_img-->', body) - pos('<!--start_img-->', body) - 16) + '</center><br>' + content;
Result := pchar(content);
end;
end.
 
function content(body: string): pchar;
//新闻内容
里面,
var
content: string;
放到函数外面去,作为全局变量就没问题了啊,当然,他的名字和函数重复,要变!
var
g_content: string;
function content(body: string): pchar;
//新闻内容
begin
g_content := copy(body, pos('<!--start_1-->', body) + 14, pos('<!--end_1-->', body) - pos('<!--start_1-->', body) - 14);
if pos('<!--start_img-->', body) <> 0 then
g_content := '<center>' + copy(body, pos('<!--start_img-->', body) + 16, pos('<!--end_img-->', body) - pos('<!--start_img-->', body) - 16) + '</center><br>' + g_content;
Result := pchar(g_content);
end;
 
to Pipi.
为什么作为全局变量就可以,有什么差别吗?
 
有,局部变量content,在函数返回的时候就释放了
它的数据pchar(content)当然也释放了。你的exe得到一个被释放的内存区域……
 
后退
顶部