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;
为什么调用的时候返回值都是为空?
20 个解决方案
#1
ads变量在函数返回后就被释放了,怎么引用???
#2
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;
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;
#3
你不應該用 result:=PChar(ads.FieldByName('ParamValue').AsString);
而是應該用 StrCopy 之類的復製,
要不然, 只是將指針簡單的指向 一版內存, 到函數結束, 那片內存(ads.FieldByName('ParamValue').AsString);) 可能已經被釋放了
我一般是這樣的
function GetSysParamEx(ParamKey:PChar; const myResult: pchar):boolean;stdcall;
而是應該用 StrCopy 之類的復製,
要不然, 只是將指針簡單的指向 一版內存, 到函數結束, 那片內存(ads.FieldByName('ParamValue').AsString);) 可能已經被釋放了
我一般是這樣的
function GetSysParamEx(ParamKey:PChar; const myResult: pchar):boolean;stdcall;
#4
aiirii(ari-爱的眼睛) 说的对,不能采用直接付值的方法
#5
aiirii(ari-爱的眼睛) 高手就是高手。
// 加一个参数 nResultSize 表示分配给 myResult 的空间大小
function GetSysParamEx(ParamKey:PChar; const myResult: pchar; const nResultSize: Integer):boolean;stdcall;
提示楼主一下:myResult 的空间是在调用 GetSysParamEx 之前分配的,而不是由 GetSysParamEx 分配。——Win32 API 中凡是用了 PChar (LPCSTR) 的,几乎都是遵循这么一个原则。
// 加一个参数 nResultSize 表示分配给 myResult 的空间大小
function GetSysParamEx(ParamKey:PChar; const myResult: pchar; const nResultSize: Integer):boolean;stdcall;
提示楼主一下:myResult 的空间是在调用 GetSysParamEx 之前分配的,而不是由 GetSysParamEx 分配。——Win32 API 中凡是用了 PChar (LPCSTR) 的,几乎都是遵循这么一个原则。
#6
pchar p;
string s;
//Pchar to string :
s:=StrPas(p);
//string to pchar :
getmem(p,length(s));
StrPCopy(p,s);
string s;
//Pchar to string :
s:=StrPas(p);
//string to pchar :
getmem(p,length(s));
StrPCopy(p,s);
#7
好!
#8
向高手学习
#9
dickeybird888(小鸟) 说的有点不对吧:
//string to pchar :
getmem(p,length(s)); // 应该是 GetMem(p, Length(s) + 1); ——字符串末尾还有个 #0.
StrPCopy(p,s);
//string to pchar :
getmem(p,length(s)); // 应该是 GetMem(p, Length(s) + 1); ——字符串末尾还有个 #0.
StrPCopy(p,s);
#10
哈哈
#11
不好意思
#12
如果在函数内部给它分配内存,那用完之后怎么释放它?
#13
分配:
GetMem(p, Size);
释放:
FreeMem(p, Size); 或 FreeMem(p);
GetMem(p, Size);
释放:
FreeMem(p, Size); 或 FreeMem(p);
#14
哈哈,其实是楼主的ads.RecordCount都是等于-1,所以返回值都是空啦
还用得着操作内存吗,汗,高手就是不同..
楼主用下面这个试试
ads.CursorLocation :=3;
ads.open;
还用得着操作内存吗,汗,高手就是不同..
楼主用下面这个试试
ads.CursorLocation :=3;
ads.open;
#15
学习
学习~
学习~
#16
向高手学习
#17
最好是在返回前把要返回的值保存起来
然后不管你的连接等怎么释放
值都不会丢失了
然后不管你的连接等怎么释放
值都不会丢失了
#18
就象楼上的说的
把结果先用个变量保存起来
然后不管你的连接怎么释放
都不会影响结果 而导致丢失了
把结果先用个变量保存起来
然后不管你的连接怎么释放
都不会影响结果 而导致丢失了
#19
Dll 中返回 String 是很麻烦的
把返回改为 WideString 的,或 Variant 的就可以了
以现在的计算机不会在乎这么点转换速度的
function GetSysParamEx(ParamKey:PChar):WideString;stdcall;
。。。
Reslt := ads.FieldByName('ParamValue').AsString;
若真的要返回 String 要保证 String 在Dll 中不被释放,并且在主程序中不被修改才可以
一般讲来返回 const 值和 dll中的全局变量是可以的,尽量还是用 WideString
把返回改为 WideString 的,或 Variant 的就可以了
以现在的计算机不会在乎这么点转换速度的
function GetSysParamEx(ParamKey:PChar):WideString;stdcall;
。。。
Reslt := ads.FieldByName('ParamValue').AsString;
若真的要返回 String 要保证 String 在Dll 中不被释放,并且在主程序中不被修改才可以
一般讲来返回 const 值和 dll中的全局变量是可以的,尽量还是用 WideString
#20
GetMem(p, Length(s)+1); //字符串末尾还有个 #0.
StrPCopy(p,s);
result := p;
这样写可以通过,但会不会造成内存泄漏?
StrPCopy(p,s);
result := p;
这样写可以通过,但会不会造成内存泄漏?
#21
#1
ads变量在函数返回后就被释放了,怎么引用???
#2
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;
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;
#3
你不應該用 result:=PChar(ads.FieldByName('ParamValue').AsString);
而是應該用 StrCopy 之類的復製,
要不然, 只是將指針簡單的指向 一版內存, 到函數結束, 那片內存(ads.FieldByName('ParamValue').AsString);) 可能已經被釋放了
我一般是這樣的
function GetSysParamEx(ParamKey:PChar; const myResult: pchar):boolean;stdcall;
而是應該用 StrCopy 之類的復製,
要不然, 只是將指針簡單的指向 一版內存, 到函數結束, 那片內存(ads.FieldByName('ParamValue').AsString);) 可能已經被釋放了
我一般是這樣的
function GetSysParamEx(ParamKey:PChar; const myResult: pchar):boolean;stdcall;
#4
aiirii(ari-爱的眼睛) 说的对,不能采用直接付值的方法
#5
aiirii(ari-爱的眼睛) 高手就是高手。
// 加一个参数 nResultSize 表示分配给 myResult 的空间大小
function GetSysParamEx(ParamKey:PChar; const myResult: pchar; const nResultSize: Integer):boolean;stdcall;
提示楼主一下:myResult 的空间是在调用 GetSysParamEx 之前分配的,而不是由 GetSysParamEx 分配。——Win32 API 中凡是用了 PChar (LPCSTR) 的,几乎都是遵循这么一个原则。
// 加一个参数 nResultSize 表示分配给 myResult 的空间大小
function GetSysParamEx(ParamKey:PChar; const myResult: pchar; const nResultSize: Integer):boolean;stdcall;
提示楼主一下:myResult 的空间是在调用 GetSysParamEx 之前分配的,而不是由 GetSysParamEx 分配。——Win32 API 中凡是用了 PChar (LPCSTR) 的,几乎都是遵循这么一个原则。
#6
pchar p;
string s;
//Pchar to string :
s:=StrPas(p);
//string to pchar :
getmem(p,length(s));
StrPCopy(p,s);
string s;
//Pchar to string :
s:=StrPas(p);
//string to pchar :
getmem(p,length(s));
StrPCopy(p,s);
#7
好!
#8
向高手学习
#9
dickeybird888(小鸟) 说的有点不对吧:
//string to pchar :
getmem(p,length(s)); // 应该是 GetMem(p, Length(s) + 1); ——字符串末尾还有个 #0.
StrPCopy(p,s);
//string to pchar :
getmem(p,length(s)); // 应该是 GetMem(p, Length(s) + 1); ——字符串末尾还有个 #0.
StrPCopy(p,s);
#10
哈哈
#11
不好意思
#12
如果在函数内部给它分配内存,那用完之后怎么释放它?
#13
分配:
GetMem(p, Size);
释放:
FreeMem(p, Size); 或 FreeMem(p);
GetMem(p, Size);
释放:
FreeMem(p, Size); 或 FreeMem(p);
#14
哈哈,其实是楼主的ads.RecordCount都是等于-1,所以返回值都是空啦
还用得着操作内存吗,汗,高手就是不同..
楼主用下面这个试试
ads.CursorLocation :=3;
ads.open;
还用得着操作内存吗,汗,高手就是不同..
楼主用下面这个试试
ads.CursorLocation :=3;
ads.open;
#15
学习
学习~
学习~
#16
向高手学习
#17
最好是在返回前把要返回的值保存起来
然后不管你的连接等怎么释放
值都不会丢失了
然后不管你的连接等怎么释放
值都不会丢失了
#18
就象楼上的说的
把结果先用个变量保存起来
然后不管你的连接怎么释放
都不会影响结果 而导致丢失了
把结果先用个变量保存起来
然后不管你的连接怎么释放
都不会影响结果 而导致丢失了
#19
Dll 中返回 String 是很麻烦的
把返回改为 WideString 的,或 Variant 的就可以了
以现在的计算机不会在乎这么点转换速度的
function GetSysParamEx(ParamKey:PChar):WideString;stdcall;
。。。
Reslt := ads.FieldByName('ParamValue').AsString;
若真的要返回 String 要保证 String 在Dll 中不被释放,并且在主程序中不被修改才可以
一般讲来返回 const 值和 dll中的全局变量是可以的,尽量还是用 WideString
把返回改为 WideString 的,或 Variant 的就可以了
以现在的计算机不会在乎这么点转换速度的
function GetSysParamEx(ParamKey:PChar):WideString;stdcall;
。。。
Reslt := ads.FieldByName('ParamValue').AsString;
若真的要返回 String 要保证 String 在Dll 中不被释放,并且在主程序中不被修改才可以
一般讲来返回 const 值和 dll中的全局变量是可以的,尽量还是用 WideString
#20
GetMem(p, Length(s)+1); //字符串末尾还有个 #0.
StrPCopy(p,s);
result := p;
这样写可以通过,但会不会造成内存泄漏?
StrPCopy(p,s);
result := p;
这样写可以通过,但会不会造成内存泄漏?