关于DLL中不能使用STRING的问题 ( 积分: 100 )

  • 主题发起人 skywater007
  • 开始时间
S

skywater007

Unregistered / Unconfirmed
GUEST, unregistred user!
各位大哥大姐,问个问题:

我现在正在写一个DLL,看书上说最好不要使用STRING,应该用PCHAR,所以我把所有STRING类型的数据改为PCHAR型了,但是新的问题出现了,有些DELPHI的函数是要用到STRING的,如
var
a : pchar
begin
setlength(a,64);
delete(a,1,5);
end;
这两个函数都分别报出了错误,请问该如何解决呢?
end
 
S

skywater007

Unregistered / Unconfirmed
GUEST, unregistred user!
各位大哥大姐,问个问题:

我现在正在写一个DLL,看书上说最好不要使用STRING,应该用PCHAR,所以我把所有STRING类型的数据改为PCHAR型了,但是新的问题出现了,有些DELPHI的函数是要用到STRING的,如
var
a : pchar
begin
setlength(a,64);
delete(a,1,5);
end;
这两个函数都分别报出了错误,请问该如何解决呢?
end
 
B

bhg007

Unregistered / Unconfirmed
GUEST, unregistred user!
var
a : pchar
begin
setlength(string(a),64);
delete(string(a),1,5);
end;
 
H

huiyue

Unregistered / Unconfirmed
GUEST, unregistred user!
可以用string的,只不过,这样的dll只能用delphi来调用了。
如果要做到通用呢,才需要用pchar
 
N

nicai_wgl

Unregistered / Unconfirmed
GUEST, unregistred user!
如果你的DLL只是自己用的话可以用string的,
在Uses的最前面加上 ShareMem 就可以了。
 
S

skywater007

Unregistered / Unconfirmed
GUEST, unregistred user!
谢谢楼上的各位,但是我写的DLL是要给PB或者其他应用程序调用的,所以必须通用啊,有没有什么办法解决啊?

1楼的兄弟,这样做,还是用到了STRING类型啊,其他调用也是出错的
 
P

plenilune168

Unregistered / Unconfirmed
GUEST, unregistred user!
DLL里面是可以用String,只要传递的参数不是String就不用担心。参数可以用PChar,函数内部再转换
 
V

vvyang

Unregistered / Unconfirmed
GUEST, unregistred user!
如果你的字符串长度不超过 255,完全可以用 ShortString,用法同 String,并且可以用在 Dll 中:
var
a: ShortString;
begin
SetLength(a, 64);
Delete(a, 1, 5);
end;
 
S

skywater007

Unregistered / Unconfirmed
GUEST, unregistred user!
// delete(In_Str_NeedSplit, 1,Pv_Int_postion );
MoveMemory(Pchar(In_Str_NeedSplit),Pchar(length(In_Str_NeedSplit))+Pv_Int_postion,length(In_Str_NeedSplit)-Pv_Int_postion-1);
哪位大哥帮我看看,这样的转化为什么出错呢?
 
L

lxw5214

Unregistered / Unconfirmed
GUEST, unregistred user!
我记得好像是在传参数时要用pchar,内部可用string吧,你在内部转换一下就好了
 
V

vvyang

Unregistered / Unconfirmed
GUEST, unregistred user!
1、同志哥,你这都写些什么啊?看看 MoveMemory 的声明:
procedure MoveMemory(Destination: Pointer
Source: Pointer
Length: DWORD);
第一个参数是目的地址,第二个参数是源地址,你把字符串的长度移到字符串里干什么??
2、另外 In_Str_NeedSplit、Pv_Int_postion 这两个变量是什么类型、干什么的,你准备实现什么功能,请说清楚,我们没时间跟你猜哑谜。
 
S

skywater007

Unregistered / Unconfirmed
GUEST, unregistred user!
呵呵,不好意思
1.delete(In_Str_NeedSplit, 1,Pv_Int_postion )
in_str_needsplit:pchar类型:传入的字符串;
Pv_int_postion:integer类型:传入的字符串的起始位置;
做个例子:我传入的是|A|B|,经过delete后就是 A|B|

2.另外有个问题:
我定义了一个函数function test(Var a :Array of Pchar):boolean;

我这样调用它:
procedure testf;
var
b : array of Pchar;
begin
setlength(b,10);
test(b);
showmessage(b[1]);
end;

可以确定我函数没有错,输出的数据在函数内部可以看到结果,为什么我调用的时候却得到空的结果?
 
W

wzca

Unregistered / Unconfirmed
GUEST, unregistred user!
DLL 里可以用String 呀
只是在接口部分别用string就行了
 
L

liuxiangsoft

Unregistered / Unconfirmed
GUEST, unregistred user!
加入sharemem
這個單元試試
 
S

skywater007

Unregistered / Unconfirmed
GUEST, unregistred user!
function TForm1.PcharSplit(In_Str_NeedSplit:pchar;Var Out_Arr_Splited:Array of Pchar):Boolean ;
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 ;

大家看看,这个函数我已经发上来了,为什么我调用的时候是空植呢?
 
V

vvyang

Unregistered / Unconfirmed
GUEST, unregistred user!
1、你写的函数不能用,因为动态数组不能作为参数在 dll 中传递。给你写了一个,Out_Count 返回分割的字符串数,函数返回字符串地址列表在内存中的地址。
function PCharSplit(const In_Str_NeedSplit: PChar
var Out_Count: Longint): PPChar;
var
hMem: LongWord;
p: PChar;
flag: LongBool;
head: array[0..65535] of PChar;
pp: PPChar;
i: Longint;
begin
hMem := GlobalAlloc(GMEM_MOVEABLE, StrLen(In_Str_NeedSplit) + 1);
p := GlobalLock(hMem);
StrCopy(p, In_Str_NeedSplit);
GlobalUnlock(hMem);
flag := False;
Out_Count := 0;
while p^ <> #0 do
begin
if p^ = '|' then
begin
p^ := #0;
if flag then flag := False;
end
else if not flag then
begin
head[Out_Count] := p;
Inc(Out_Count);
flag := True;
end;
Inc(p);
end;
hMem := GlobalAlloc(GMEM_MOVEABLE, Out_Count * SizeOf(PChar));
Result := GlobalLock(hMem);
pp := Result;
i := 0;
while i < Out_Count do
begin
pp^ := head;
Inc(pp);
Inc(i);
end;
GlobalUnlock(hMem);
end;
2、这个函数这么使用
var
s: PChar;
pp: PPChar;
count, i: Integer;
begin
s := '|ab|cd|e|fghi|';
pp := PCharSplit(s, count);
for i := 0 to count - 1 do
begin
ShowMessage(pp^);
Inc(pp, 1);
end;
end;
 
S

skywater007

Unregistered / Unconfirmed
GUEST, unregistred user!
谢谢这位兄弟,这个函数好象复杂了点,:)

再问一下,如果我这个函数是在DLL中的各个单元之间调用的,可以用Array of String 吗?如果可以,就不用那么费劲了,因为我这个函数不给外界用的。
 
B

bbscom

Unregistered / Unconfirmed
GUEST, unregistred user!
如果用STRING類型改為WideString類型就可以了。
 
S

skywater007

Unregistered / Unconfirmed
GUEST, unregistred user!
to bbscom:
你 试过 没有的啊?我好像试过不行。:)

to plenilune168 ,
“DLL里面是可以用String,只要传递的参数不是String就不用担心。参数可以用PChar,函数内部再转换”,您确定这样能行的吗?因为我是第一次做DLL:)

谢谢!!!
 
P

plenilune168

Unregistered / Unconfirmed
GUEST, unregistred user!
“DLL里面是可以用String,只要传递的参数不是String就不用担心。参数可以用PChar,函数内部再转换”是没有问题的

如果出错就是你函数内部程序的问题
 
顶部