动态链接库返回字符串的问题,有程序.

zhouming2000 2005-02-01 04:49:14
function GetSysParamEx(ParamKey:PChar):PChar;stdcall;
var
cnn:TAdoConnection;
ads:TAdoDataSet;
begin
cnn:=TADOConnection.Create(Application);
cnn.ConnectionString:= GetConnectionString;
cnn.LoginPrompt:=false;
cnn.Open;
ads:=TAdoDataSet.Create(Application);
ads.Connection:=cnn;
ads.Close;
ads.CommandText:='select * from SSysParams where ParamKey=''MaxConsumption''';
ads.Open;
if ads.RecordCount>0 then
begin
result:=PChar(ads.FieldByName('ParamValue').AsString);
end
else
result:='';
ads.Free;
cnn.Free;
end;

为什么调用的时候返回值都是为空?
...全文
183 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
jialiuer 2005-02-03
  • 打赏
  • 举报
回复
GetMem(p, Length(s)+1); //字符串末尾还有个 #0.
StrPCopy(p,s);
result := p;
这样写可以通过,但会不会造成内存泄漏?
surpassable 2005-02-02
  • 打赏
  • 举报
回复
学习
学习~
DieGhost 2005-02-02
  • 打赏
  • 举报
回复
哈哈,其实是楼主的ads.RecordCount都是等于-1,所以返回值都是空啦
还用得着操作内存吗,汗,高手就是不同..

楼主用下面这个试试
ads.CursorLocation :=3;
ads.open;
zhengji 2005-02-02
  • 打赏
  • 举报
回复
分配:
GetMem(p, Size);
释放:
FreeMem(p, Size); 或 FreeMem(p);
zhouming2000 2005-02-02
  • 打赏
  • 举报
回复
如果在函数内部给它分配内存,那用完之后怎么释放它?
xzq 2005-02-02
  • 打赏
  • 举报
回复
Dll 中返回 String 是很麻烦的
把返回改为 WideString 的,或 Variant 的就可以了
以现在的计算机不会在乎这么点转换速度的

function GetSysParamEx(ParamKey:PChar):WideString;stdcall;
。。。
Reslt := ads.FieldByName('ParamValue').AsString;
若真的要返回 String 要保证 String 在Dll 中不被释放,并且在主程序中不被修改才可以
一般讲来返回 const 值和 dll中的全局变量是可以的,尽量还是用 WideString
Kshape 2005-02-02
  • 打赏
  • 举报
回复
就象楼上的说的
把结果先用个变量保存起来
然后不管你的连接怎么释放
都不会影响结果 而导致丢失了
Kshape 2005-02-02
  • 打赏
  • 举报
回复
最好是在返回前把要返回的值保存起来
然后不管你的连接等怎么释放
值都不会丢失了
Kshape 2005-02-02
  • 打赏
  • 举报
回复
向高手学习
dickeybird888 2005-02-01
  • 打赏
  • 举报
回复
不好意思
dickeybird888 2005-02-01
  • 打赏
  • 举报
回复
哈哈
zhengji 2005-02-01
  • 打赏
  • 举报
回复
dickeybird888(小鸟) 说的有点不对吧:
//string to pchar :
getmem(p,length(s)); // 应该是 GetMem(p, Length(s) + 1); ——字符串末尾还有个 #0.
StrPCopy(p,s);
cdsgajxlp 2005-02-01
  • 打赏
  • 举报
回复
向高手学习
何鲁青 2005-02-01
  • 打赏
  • 举报
回复
好!
dickeybird888 2005-02-01
  • 打赏
  • 举报
回复
pchar p;
string s;

//Pchar to string :
s:=StrPas(p);

//string to pchar :
getmem(p,length(s));
StrPCopy(p,s);
zhengji 2005-02-01
  • 打赏
  • 举报
回复
aiirii(ari-爱的眼睛) 高手就是高手。

// 加一个参数 nResultSize 表示分配给 myResult 的空间大小
function GetSysParamEx(ParamKey:PChar; const myResult: pchar; const nResultSize: Integer):boolean;stdcall;

提示楼主一下:myResult 的空间是在调用 GetSysParamEx 之前分配的,而不是由 GetSysParamEx 分配。——Win32 API 中凡是用了 PChar (LPCSTR) 的,几乎都是遵循这么一个原则。
dickeybird888 2005-02-01
  • 打赏
  • 举报
回复
aiirii(ari-爱的眼睛) 说的对,不能采用直接付值的方法
aiirii 2005-02-01
  • 打赏
  • 举报
回复
你不應該用 result:=PChar(ads.FieldByName('ParamValue').AsString);
而是應該用 StrCopy 之類的復製,
要不然, 只是將指針簡單的指向 一版內存, 到函數結束, 那片內存(ads.FieldByName('ParamValue').AsString);) 可能已經被釋放了

我一般是這樣的
function GetSysParamEx(ParamKey:PChar; const myResult: pchar):boolean;stdcall;
syl79 2005-02-01
  • 打赏
  • 举报
回复
function GetSysParamEx(ParamKey:PChar):PChar;stdcall;
var
cnn:TAdoConnection;
ads:TAdoDataSet;
p : pchar;
begin
cnn:=TADOConnection.Create(Application);
cnn.ConnectionString:= GetConnectionString;
cnn.LoginPrompt:=false;
cnn.Open;
ads:=TAdoDataSet.Create(Application);
ads.Connection:=cnn;
ads.Close;
ads.CommandText:='select * from SSysParams where ParamKey=''MaxConsumption''';
ads.Open;
if ads.RecordCount>0 then
begin
getmem (p,length (FieldByName('ParamValue').AsString));
...//复制到P
result:=p;
end
else
result:='';
ads.Free;
cnn.Free;
end;
syl79 2005-02-01
  • 打赏
  • 举报
回复
ads变量在函数返回后就被释放了,怎么引用???

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧