如何在DLL过程中使用变参?兄弟们一定要帮忙阿,HURRY(100分)

  • 主题发起人 主题发起人 xewei
  • 开始时间 开始时间
X

xewei

Unregistered / Unconfirmed
GUEST, unregistred user!
我想在我的DLL中使用变参以返回多个变量,可是出错.
我使用了PCHAR类型代替STRING仍然出错
本想用自定义类型实现此功能,但不知道DLL是否支持导出DLL自定义类型,如我自定义的类或记录集

以下是代码

{DLL定义的过程}
procedure GetRegUserInfo(var UserName,SerialNo,UnitName,UserAddr,Email,UserPhone:Pchar);far;
var
reg:TRegistry;
begin
//初始化
UserName := '';
SerialNo := '';
UnitName := '';
UserAddr := '';
Email := '';
UserPhone := '';
reg:=TRegistry.Create;//创建实例
reg.RootKey:=HKEY_CURRENT_USER;//指定需要操作的注册表的主键
if reg.OpenKey(FDRegDirectory,true) then//如果打开成功则进行以下操作
begin
UserName := Pchar(reg.ReadString(FDRegUserName));
SerialNo := Pchar(reg.ReadString(FDRegSerialNo));
UnitName := Pchar(reg.ReadString(FDRegUnitName));
UserAddr := Pchar(reg.ReadString(FDRegUserAddr));
Email := Pchar(reg.ReadString(FDRegEmail));
UserPhone := Pchar(reg.ReadString(FDRegUserPhone));
end;
reg.CloseKey;//关闭注册表
reg.Free;//释放变量所占内存
end;

{调用DLL}
procedure TRegisterForm.FormCreate(Sender: TObject);
type
TProc = Procedure(var UserName,SerialNo,UnitName,UserAddr,Email,UserPhone:Pchar);
var
Th:Thandle;
Tc:TProc;
Tp:TFarProc;
UserName,SerialNo,UnitName,UserAddr,Email,UserPhone:Pchar;
begin
Th:=LoadLibrary('cxw.dll')
{装载DLL}
if Th>0 then
try
Tp:=GetProcAddress(Th,PChar('GetRegUserInfo'));
if Tp<>nil
then begin
Tc:=TProc(Tp);
/////////////////////////////////////
//此处出错,一定要帮我解决阿
/////////////////////////////////////
Tc(UserName,SerialNo,UnitName,UserAddr,Email,UserPhone)
{调用过程}
end
else
begin
Application.MessageBox('GetRegUserInfo过程没有找到!','错误',MB_OK+MB_ICONERROR);
application.Terminate;
end;
finally
FreeLibrary(Th)
{释放DLL}
end
else
begin
Application.MessageBox('Cxw.dll没有找到!','错误',MB_OK+MB_ICONERROR);
application.Terminate;
end;
if trim(string(UserName))='' then
begin
Application.MessageBox('您不是本软件注册用户,请注册!','软件注册',MB_OK+MB_ICONINFORMATION);
end
else
begin
edUserName.Text := string(UserName);
edSerialNumber.Text := string(SerialNo);
edUnitName.Text := string(UnitName);
edUserAddr.Text := string(UserAddr);
edEmail.Text := string(Email);
edUserPhone.Text := string(UserPhone);

edUserName.Enabled := false;
edSerialNumber.Enabled := false;
edUnitName.Enabled := false;
edUserAddr.Enabled := false;
edEmail.Enabled := false;
edUserPhone.Enabled := false;
btnRegister.Enabled := false;
end;
end;
 
up,顺便也看看下面的问题。谢谢
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1746656
 
PChar最好是用API HeapAlloc什么的分配内存,不要用string类型来转换,否则容易出问题
 
楼上的,问题不处在STRING强制类型转换,因为调用DLL过程已经出错了,而DLL过程没有使用
STRING强制类型转换
 
在调用DLL之前,先给UserName,SerialNo,UnitName,UserAddr,Email,UserPhone分配好
内存试一下。
另外以下代码不要放在DLL中:
UserName := '';
SerialNo := '';
UnitName := '';
UserAddr := '';
Email := '';
UserPhone := '';
 
同志们,不要不管我啊
HELP+SOS
 
没有人愿意再加入话题,是分数太少了,还是不屑于回答?
不要再做沉默的羔羊啊
 
这段代码有问题,你调用的地方只是声明了一些PChar,他们的值是随机的,
况且没有给这些PChar申请内存。
UserName := Pchar(reg.ReadString(FDRegUserName));
SerialNo := Pchar(reg.ReadString(FDRegSerialNo));
UnitName := Pchar(reg.ReadString(FDRegUnitName));
UserAddr := Pchar(reg.ReadString(FDRegUserAddr));
Email := Pchar(reg.ReadString(FDRegEmail));
UserPhone := Pchar(reg.ReadString(FDRegUserPhone));

以一个变量举例(其他照抄)应该这样:

调用的地方如下:
var
UserName: string;
n: integer;
begin
setLength(UserName, 100 {假设你知道最长100个字符});
GetUserInfo(pchar(UserName), ....);
//由于假定的100可能太大
if pos(#0, UserName) > 0 then
SetLength(UserName, pos(#0, UserName) - 1);
...
end;

DLL里的写法:
procedure GetRegUserInfo(var UserName,SerialNo,UnitName,UserAddr,Email,UserPhone:Pchar);
var
tmp: string;
begin
....

tmp := reg.ReadString(FDRegUserName);
FillChar(UserName^,100, 0);
if length(tmp) > 100 then
tmp := copy(tmp, 1, 100);
move(pchar(tmp)^, UserName^, length(tmp))

...
end;
 
Tc:=TProc(Tp)
//去掉这句试试
/////////////////////////////////////
//此处出错,一定要帮我解决阿
/////////////////////////////////////
 
多人接受答案了。
 
后退
顶部