为什么我在DLL中创建的ADOCONNECTION出错呢?(50分)

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

JUMP1972

Unregistered / Unconfirmed
GUEST, unregistred user!
在DLL中导出的一个函数:传入一个格式文件路径,一个编号,一个日期,及返回的字符串
部分代码如下:
function GetCustPowerFee(TicketFilePath,Account_id,ym:string;QueryTxt:PChar):integer;
var
F:TextFile;
ADOCon:TADOConnection;
ADODataSet1:TADODataSet;

QueryTxt1,QueryTxt2:Widestring;
TicketFileName1,TicketFileName2,TmpStr,TmpStr2,FmtStr1,FmtStr2:string;
FixLen1,FixLen2,i,iPos:integer;
AppPath,DataSource,DBName,UID,Pwd:string;
begin
Result:=0;
QueryTxt1:='';
QueryTxt2:='';
FixLen1:=20;
FixLen2:=16;

AppPath:=ExtractFilePath(Application.ExeName);
with TIniFile.Create(AppPath+'DSFile.ini') do
try  //从配置文件中读出连接字符串的参数
DataSource:=ReadString('DataSourceSet','DBServerIP','');
UID:=ReadString('DataSourceSet','UID','');
Pwd:=ReadString('DataSourceSet','PWD','');
DBName:=ReadString('DataSourceSet','DBName','');
finally
Free;
end;
ConnFmt:='Provider=SQLOLEDB.1;Persist Security Info=false;Data Source=%s;'+
'Initial Catalog=%s;User ID=%s;PassWord=%s';
// ADOCon:=TADOConnection.Create(Application);
ADOCon:=TADOConnection.Create(nil);
with ADOCon do
try
Connected:=false;
KeepConnection:=false;
LoginPrompt:=false;
ConnectionString:=Format(ConnFmt,[DataSource,DBName,UID,pwd])
//出错:OLE错误
Connected:=true;
KeepConnection:=true;
ADODataSet1:=TADODataSet.Create(Application);
with ADODataSet1 do //取电费数据
try
Connection:=ADOCon;
CommandType:=cmdStoredProc;
Active:=false;
if Parameters.Count>0 then Parameters.Refresh;
CommandText:='p_GetCustPowerFee';
Parameters.Refresh;
Parameters[1].Value:=Account_id;
Parameters[2].Value:=StrToInt(Copy(ym,1,4));
Parameters[3].Value:=StrToInt(Copy(ym,5,2));
Active:=true;

不知道为什么出错?
请高手解惑
 
首先在dll中混用string和pchar的习惯很不好
应该统一使用pchar类型
否则你应在调用此dll的项目文件(注意是项目文件)第一个引用位置处引用上sharemem

按照你的情况像是没有初始化com的错误
在调用此dll的主窗体的最后加上两句试试
initialization
CoInitialize(nil);
finalization
CoUninitialize;
 
之前先要

uses ActiveX;
...
CoInitialize(nil);
ADOCon:=TADOConnection.Create(nil);
...
 
to 52free:
  谢谢!
  这个DLL是供另的DLL调用的,也就是说我这个函数必须独立的完成。
  我不明白为什么ADOCONNECTION.Active:=true时出错。
 
我觉得
initialization
CoInitialize(nil);
finalization
CoUninitialize;
写在这个dll的单元里较好一些
 
这段代码:initialization
CoInitialize(nil);
finalization
CoUninitialize;

我加上了,不起作用!我觉得不应该是这个原因。adoconnection创建时未出错,在Active:=true时出错。

to all:
能否抽时间写段代码,试试!

 
你的 AppPath:=ExtractFilePath(Application.ExeName)
取得路径是host的路径
取dll的路径要用GetModuleFileName
 
to 迷糊:
GetModuleFileName 怎么用呢?
 
function getpath: string;
var
tmpstr:string;
begin
SetLength(tmpstr, 200);
SetLength(tmpstr, GetModuleFileName(HInstance, PChar(tmpstr), length(tmpstr)));
Result:= ExtractFilePath(tmpstr);
end;
 
谢谢 迷糊!
请继续.
 
这个DLL中只有一个单元,就是导出这个函数,没有Form、DataModule.
请大家继续,知无不言,言无不尽。
 
不如你贴完整些,大家好帮你调试一下
 
完整的代码如下:
library FaxForIVR;
uses
uFaxDll in 'uFaxDll.pas';
exports
GetCustPowerFee;

{$R *.RES}

begin
end.

unit uFaxDll;

interface

uses Windows, ADODB, SysUtils, Forms,Printers,classes,dialogs,IniFiles;

{var
ConnFmt:widestring;
DataSource,DBName,UID,Pwd:string;}

function GetCustPowerFee(TicketFilePath,Account_id,ym:string;QueryTxt:PChar):integer
stdcall;

implementation

Function Spaces(i:Byte):String;
Var
zip : String[255];
Begin
FillChar(zip,i+1,' ');
zip[0] := Chr(i);
Spaces := Zip;
End;

//TicketFilePath:票据文件所在路径,Account_id:账户ID,ym:电费年月如200301,QueryTxt:查询结果
//返回值:
// 0:失败(或查询结果为空)
// 1:成功(有数据,则返回查询结果 包括电费及每块电表的指示数)
function GetCustPowerFee(TicketFilePath,Account_id,ym:string;QueryTxt:PChar):integer;
var
F:TextFile;
ADOCon:TADOConnection;
ADODataSet1:TADODataSet;

QueryTxt1,QueryTxt2:Widestring;
TicketFileName1,TicketFileName2,TmpStr,TmpStr2,FmtStr1,FmtStr2:string;
// SQLResult:array of string;
FixLen1,FixLen2,i,iPos:integer;
AppPath,DataSource,DBName,UID,Pwd:string;
ConnFmt:widestring;
begin
Result:=0;
QueryTxt1:='';
QueryTxt2:='';
FixLen1:=20;
FixLen2:=16;

AppPath:=ExtractFilePath(Application.ExeName);
with TIniFile.Create(AppPath+'DSFile.ini') do
try
DataSource:=ReadString('DataSourceSet','DBServerIP','');
UID:=ReadString('DataSourceSet','UID','');
Pwd:=ReadString('DataSourceSet','PWD','');
DBName:=ReadString('DataSourceSet','DBName','');
finally
Free;
end;
ConnFmt:='Provider=SQLOLEDB.1;Persist Security Info=false;Data Source=%s;'+
'Initial Catalog=%s;User ID=%s;PassWord=%s';
{ DataSource:='ctiserver';
UID:='sa';
Pwd:='';
DBName:='bycall';}
ADOCon:=TADOConnection.Create(Application);
// ADOCon:=TADOConnection.Create(nil);
with ADOCon do
try
Connected:=false;
KeepConnection:=false;
LoginPrompt:=false;
ConnectionString:=Format(ConnFmt,[DataSource,DBName,UID,pwd]);
Connected:=true;
KeepConnection:=true;
if Copy(TicketFilePath,Length(TicketFilePath),1)<>'/' then
TicketFilePath:=TicketFilePath+'/';
TicketFileName1:=TicketFilePath+'TicketFee.txt'

TicketFileName2:=TicketFilePath+'TicketGage.txt';
if (not FileExists(TicketFileName1)) or (not FileExists(TicketFileName2)) then Exit;
AssignFile(F,TicketFileName1);
try
TmpStr:='';
Reset(F);
while not Eof(F) do
begin
Readln(F,TmpStr);
QueryTxt1:=QueryTxt1+TmpStr+#13+#10;
end;
finally
CloseFile(F);
end;
FmtStr1:='%'+IntToStr(-FixLen1)+'s';
QueryTxt1:=StringReplace(QueryTxt1,'%s',FmtStr1,[rfReplaceAll, rfIgnoreCase]);
AssignFile(F,TicketFileName2);
try
TmpStr:='';
Reset(F);
while not Eof(F) do
begin
Readln(F,TmpStr);
QueryTxt2:=QueryTxt2+TmpStr+#13+#10;
end;
finally
CloseFile(F);
end;
FmtStr2:='%'+IntToStr(-FixLen2)+'s';
QueryTxt2:=StringReplace(QueryTxt2,'%s',FmtStr2,[rfReplaceAll, rfIgnoreCase]);
ADODataSet1:=TADODataSet.Create(Application);
with ADODataSet1 do //取电费数据
try
CommandTimeout:=0;
Connection:=ADOCon;
CommandType:=cmdStoredProc;
Active:=false;
if Parameters.Count>0 then Parameters.Refresh;
CommandText:='p_GetCustPowerFee';
Parameters.Refresh;
Parameters[1].Value:=Account_id;
Parameters[2].Value:=StrToInt(Copy(ym,1,4));
Parameters[3].Value:=StrToInt(Copy(ym,5,2));
Active:=true;
if RecordCount=0 then
begin //电费数据写入临时文件
Exit;
end;
for i:=0 to FieldCount-1 do
if pos(FmtStr1,QueryTxt1)=0 then Break
else
begin
if Fields.IsNull then
TmpStr:=' '
else
TmpStr:=trim(Fields.AsString);
iPos:=pos(FmtStr1,QueryTxt1)+Length(FmtStr1);
TmpStr2:=Copy(QueryTxt1,1,iPos);
TmpStr2:=Format(TmpStr2,[TmpStr]);
QueryTxt1:=TmpStr2+Copy(QueryTxt1,iPos+1,Length(QueryTxt1));
end

QueryTxt1:=StringReplace(QueryTxt1,FmtStr1,Spaces(FixLen1),[rfReplaceAll, rfIgnoreCase]);
Active:=false
//取表指示数据
if Parameters.Count>0 then Parameters.Refresh;
CommandText:='p_GetCustGageDisp';
Parameters.Refresh;
Parameters[1].Value:=Account_id;
Parameters[2].Value:=StrToInt(Copy(ym,1,4));
Parameters[3].Value:=StrToInt(Copy(ym,5,2));
Active:=true;
while (not eof) and (pos(FmtStr2,QueryTxt2)>0) do
begin
for i:=0 to FieldCount-1 do
if pos(FmtStr2,QueryTxt2)=0 then Break
else
begin
if Fields.IsNull then
TmpStr:=' '
else
TmpStr:=trim(Fields.AsString);
iPos:=pos(FmtStr2,QueryTxt2)+Length(FmtStr2);
TmpStr2:=Copy(QueryTxt2,1,iPos);
TmpStr2:=Format(TmpStr2,[TmpStr]);
QueryTxt2:=TmpStr2+Copy(QueryTxt2,iPos+1,Length(QueryTxt2));
end;
Next;
end;
QueryTxt2:=StringReplace(QueryTxt2,FmtStr2,Spaces(FixLen2),[rfReplaceAll,rfIgnoreCase]);
StrPCopy(QueryTxt,QueryTxt1+QueryTxt2);
Result:=1;
finally
Close;
Connection:=nil;
Free;
end;
finally
Connected:=false;
KeepConnection:=false;
Free;
end;
end;

end.
 
代码已经贴上了,请大家给点意见.
 
后退
顶部