各位大哥大姐,问个问题:我现在正在写一个DLL,看书上说最好不要使用STRING,应该用PCHAR,所以我把所有STRING类型的数据改为PCHAR型了,但是新的问题出现了,有些DELPHI的函数是要用到STRING的,如
var
a : pchar
begin
setlength(a,64);
delete(a,1,5);
end;
这两个函数都分别报出了错误,请问该如何解决呢?
end
var
a : pchar
begin
setlength(a,64);
delete(a,1,5);
end;
这两个函数都分别报出了错误,请问该如何解决呢?
end
var
a:pChar;
begin
GetMem(a,64);
MoveMemory(a,a+5,59);
FreeMem(a);
end
MoveMemory(Pchar(In_Str_NeedSplit),Pchar(length(In_Str_NeedSplit))+Pv_Int_postion,length(In_Str_NeedSplit)-Pv_Int_postion-1);请问大哥,这个怎么转换啊?怎么出错啊
a : pchar
s:string;
begin
setlength(s,64);
delete(s,1,5);
a := Pchar(s);
... doSomething
end;
补充一下,同意 freeman9507(自由人)的说法,很经典
{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }
上面的意思就是说如果你的DLL中用到了string参数或者返回值,那么在DLL单元和工程单元的Uses字句中第一个引用ShareMem 单元.只是如果用delphi编写DLL供其他语言编写的程序调用就尽量不要用string,用PChar.
procedure testf;
var
b : array of Pchar;
begin
setlength(b,10);
test(b);
showmessage(b[1]);
end;可以确定我函数没有错,输出的数据在函数内部可以看到结果,为什么我调用的时候却得到空的结果?
Var
Pv_Int_postion,pv_Int_Rows : integer;
Pv_Str_NeedSplit : String;
BEGIN
Try
Result:=True;
Pv_Str_NeedSplit := In_Str_NeedSplit;
Pv_Int_postion := pos('|',Pv_Str_NeedSplit) ;
if Pv_Int_postion =1 then
begin
delete(Pv_Str_NeedSplit, 1,Pv_Int_postion );
Pv_Int_postion := pos('|',Pv_Str_NeedSplit);
end;
pv_Int_Rows:=0; while ( Pv_Int_postion > 0 ) do
begin
Out_Arr_Splited[pv_Int_Rows] := Pchar(copy(Pv_Str_NeedSplit, 1, Pv_Int_postion - 1));
delete(Pv_Str_NeedSplit,1,Pv_Int_postion);
//showmessage(Out_Arr_Splited[pv_Int_Rows]);
pv_Int_Rows := pv_Int_Rows + 1;
Pv_Int_postion := pos('|',Pv_Str_NeedSplit);
end ;
Except
Result := False;
exit;
end;end ;大家看看,这个函数我已经发上来了,为什么我调用的时候是空植呢?
函数中通过变量 Out_Arr_Splited 带回结果,但Out_Arr_Splited是一个动态数组,你的代码中
并没有对其进行分配内存,或者说设置数组的大小.另一种设想就是,由调用者初始化这个数组
也就是说再调用前,就知道要分离出的字符串的个数,如果是这样的话,有些费解.我测试了一下
可以分隔出字符串,但执行到这条语句时" Out_Arr_Splited[pv_Int_Rows] := Pchar(copy(Pv_Str_NeedSplit, 1, Pv_Int_postion - 1));"就会报错(嘿嘿,不报错就怪了).因为我调用时没对"Out_Arr_Splited"其进行初始化。后来靠虑在程序中动态增加 Out_Arr_Splited的数组大小,但编译器不高兴了。无法完成任务。从这点来看,这个函数从根本上无法完成所要求的功能(
除非用前面说到的"费解“的方法) 为了完成字符串的分隔功能,我自己写过类似的函数,现在帖出来供参考
* 功能:根据分隔符,完成字符串的分解,把结果加入到列表中返回
* 参数说明:
* const aValue:stirng 要进行分隔的字符串
* strDelimiter:string; 分隔符,字符个数没有限制
* 返回结果:
*)
function SplitEx(const aValue:string;strDelimiter:string):TStringList;
var
Size,CurPos,EndPos:Integer;
Value:string;
begin
Result := TStringList.Create();
CurPos := 1;
EndPos := strPos(strDelimiter,aValue,CurPos);
while(EndPos > 0) do
begin
Size := EndPos - CurPos;
if Size > 0 then
begin
Value := Copy(aValue,CurPos,Size);
Result.Add(Value);
end;
CurPos := EndPos + Length(strDelimiter);
EndPos := strPos(strDelimiter,aValue,CurPos);
end;
Size := Length(aValue) - CurPos + 1;
Value := Copy(aValue,CurPos,Size);
Result.Add(Value);
end;//function StrPos(const FindString, SourceString: string; StartPos: Integer): Integer;
asm //find http://www......
PUSH ESI
PUSH EDI
PUSH EBX
PUSH EDX
TEST EAX,EAX
JE @@qt
TEST EDX,EDX
JE @@qt0
MOV ESI,EAX
MOV EDI,EDX
MOV EAX,[EAX-4]
MOV EDX,[EDX-4]
DEC EAX
SUB EDX,EAX
DEC ECX
SUB EDX,ECX
JNG @@qt0
XCHG EAX,EDX
ADD EDI,ECX
MOV ECX,EAX
JMP @@nx
@@fr: INC EDI
DEC ECX
JE @@qt0
@@nx: MOV EBX,EDX
MOV AL,BYTE PTR [ESI]
@@lp1: CMP AL,BYTE PTR [EDI]
JE @@uu
INC EDI
DEC ECX
JE @@qt0
CMP AL,BYTE PTR [EDI]
JE @@uu
INC EDI
DEC ECX
JE @@qt0
CMP AL,BYTE PTR [EDI]
JE @@uu
INC EDI
DEC ECX
JE @@qt0
CMP AL,BYTE PTR [EDI]
JE @@uu
INC EDI
DEC ECX
JNE @@lp1
@@qt0: XOR EAX,EAX
@@qt: POP ECX
POP EBX
POP EDI
POP ESI
RET
@@uu: TEST EDX,EDX
JE @@fd
@@lp2: MOV AL,BYTE PTR [ESI+EBX]
CMP AL,BYTE PTR [EDI+EBX]
JNE @@fr
DEC EBX
JE @@fd
MOV AL,BYTE PTR [ESI+EBX]
CMP AL,BYTE PTR [EDI+EBX]
JNE @@fr
DEC EBX
JE @@fd
MOV AL,BYTE PTR [ESI+EBX]
CMP AL,BYTE PTR [EDI+EBX]
JNE @@fr
DEC EBX
JE @@fd
MOV AL,BYTE PTR [ESI+EBX]
CMP AL,BYTE PTR [EDI+EBX]
JNE @@fr
DEC EBX
JNE @@lp2
@@fd: LEA EAX,[EDI+1]
SUB EAX,[ESP]
POP ECX
POP EBX
POP EDI
POP ESI
end;
1)如果你的DLL只是用于Delphi程序是可以用string和TStringList 的
2)如果要供其它语言使用,可以在包装一下String,StringList都是可以转换到PChar类型的