DLL中类型转换的问题:string-->pchar(50分)

  • 主题发起人 主题发起人 JUMP1972
  • 开始时间 开始时间
J

JUMP1972

Unregistered / Unconfirmed
GUEST, unregistred user!
在DLL中有一个函数:将传入的文本文件的内容读入内存
library FaxForIVR;

uses
windows,
SysUtils,
forms,
activex,
Classes,
printers,
inifiles,
adodb,db;
{$R *.RES}
function ReadTxt(const FileName:string;RetTxt:PChar):integer;
var
f:TFileStream;
s:String;
begin
Result:=0;
if not FileExists(FileName) then Exit;
f:=TFileStream.Create(FileName,fmOpenRead or fmShareDenyNone);
try
SetLength(s,f.Size);
f.Read(s[1],f.Size);
RetTxt:=StrPCopy(RetTxt,S);  //这一句出错:格式%s无效或与自变量不相容:为什么[:(]
Result:=1;
finally
f.Free;
end;
end;

exports
ReadTxt,
GetCustPowerFee;

begin
end.

测试代码如下:
procedure TForm1.Button1Click(Sender: TObject);
var
s:pchar;
f:TFileStream;
begin
if OpenDialog1.Execute then
begin
try
f:=TFileStream.Create(OpenDialog1.FileName,fmOpenRead);
// GetMem(s, f.Size+1000);
GetMem(s, f.Size);
f.free;
if ReadTxt(OpenDialog1.FileName,s)=1 then
// if GetCustPowerFee(ExtractFilePath(Application.Exename),'10','200306',s)=1 then
Label3.Caption:=s
else
showmessage('fail');
finally
FreeMem(s);
end;
end;
end;
 
请大侠们给点意见吧。
 
f.Read(s[1],f.Size);
出问题的应该是这句
 
to 52free:
能说详细点吗?
 
出错的是这一句:RetTxt:=StrPCopy(RetTxt,S); 格式%s无效或与自变量不相容
 
我跟踪了一下,s中确实已经有了内容,给RetTxt赋值时却出错。为什么?
 
f.Read(@s[1],f.Size);
这样试试
delphi的错误提示一般在错误发生的下一行
且有时有提示还不如无提示
 
to 52free:
f.Read(@s[1],f.Size);这句语法检查不通过。
 
RetTxt:=StrPCopy(RetTxt,S);<<改成StrPCopy(RetTxt,S);
不过总觉得是f.Read(@s[1],f.Size);的问题
 
还是不行。
 能帮我试一下上面贴的代码吗?
 
你先试试不在dll中能不能通过
 
不在DLL中可以
 
function ReadTxt(const FileName:[red]string[/red];RetTxt:PChar):integer;
Dll中建议不要用String,用PChar代替,如果一定要用,记得要在Dll及主Project的uses第一项加上SharmMem
其他的代码应该没有大问题
 
还是提示:格式%s无效或与自变量不相容
 
f.Read(s[1],f.Size);
这句保证有问题,
Read:此方法实现将数据从流中读出。函数原形为:
Function Read(var Buffer;Count:Longint):Longint;virtual;abstract;
参数Buffer为数据读出时放置的缓冲区,Count为需要读出的数据的字节数,该方法返回值为实际读出的字节数,它可以小于或等于Count中指定的值。
S的位置应该是个整型数。
 
试了一下,Dll中修改如下
function ReadTxt(FileName: PChar; RetTxt: PChar): integer;
Exe中声明
function ReadTxt(FileName: PChar; RetTxt: PChar): integer; external 'dll.dll';
测试没问题
楼主所说的提示是编译不过去还是运行时的提示?中文的错误一般都是Windows API错误
楼主还是再仔细检查一遍吧,重点放在与API相关的代码

TO 桦树皮:
>> f.Read(s[1],f.Size);
这一句肯定是没问题的[:)]
 
to pihome:
能将你的测试代码贴出来吗?
 
其实就是按我上面所说的修改了一下而已
EXE:
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
OpenDialog1: TOpenDialog;
Label3: TLabel;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

function ReadTxt(FileName: PChar; RetTxt: PChar): integer; external 'dll.dll';

procedure TForm1.Button1Click(Sender: TObject);
var
s:pchar;
f:TFileStream;
begin
if OpenDialog1.Execute then
begin
try
f:=TFileStream.Create(OpenDialog1.FileName,fmOpenRead);
// GetMem(s, f.Size+1000);
GetMem(s, f.Size);
f.free;
if ReadTxt(PChar(OpenDialog1.FileName),s)=1 then
// if GetCustPowerFee(ExtractFilePath(Application.Exename),'10','200306',s)=1 then
Label3.Caption:=s
else
showmessage('fail');
finally
FreeMem(s);
end;
end;
end;

end.

DLL:
library dll;

uses
windows,
SysUtils,
forms,
activex,
Classes,
printers,
inifiles,
adodb,
db;

{$R *.RES}

function ReadTxt(FileName: PChar; RetTxt: PChar):integer; //如果要用在其他语言的程序中,最好用stdcall
var
f: TFileStream;
s: String;
begin
Result:=0;
if not FileExists(FileName) then Exit;
f:=TFileStream.Create(FileName,fmOpenRead or fmShareDenyNone);
try
SetLength(s,f.Size);
f.Read(s[1],f.Size);
RetTxt:=StrPCopy(RetTxt,S);
Result:=1;
finally
f.Free;
end;
end;

exports
ReadTxt;
// GetCustPowerFee;

begin
end.
 
to pihome:
还是不行。你的运行环境是什么?
 
另外,中文提示是我翻译过来的。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
408
import
I
后退
顶部