我在某个dll中使用了datamodule,但不知道在dll的文件中何处添加initialization节。如果在dll文件中最后的begin--end.节中添加CoInitialize(nil)的话,dll程序即可通过,但在调用此dll程序的form运行时会出现“access violation at address XXXXXXXX”的异常。可是dll的功能又能使用,这是什么回事,怎样解决?
附上源码:
dll程序:
library saturn;uses
types,
Messages,
Windows,
comobj,
ComServ,
ActiveX,
SysUtils,
Classes,
DB,
Forms,
ADODB,
Unit1 in 'Unit1.pas' {DataModule1: TDataModule};//查询余额的函数。
//输入:用户名(string),用户的卡号(string),密码(string)
//输出:IP卡余额。类型:real
function getBalance(userId:string;cardId:string;cardPwd:string):real;stdCall;
var
dm:TDatamodule1;
begin
dm:=Tdatamodule1.Create(datamodule1);
//在下面写数据连接字。 dm.ADOConnection1.ConnectionString:='';
dm.ADOQuery1.Connection:=dm.ADOConnection1;
dm.ADOQuery1.Close;
dm.ADOQuery1.SQL.Clear;
//在下面写Transact SQL语句。
dm.ADOQuery1.SQL.Add(''); dm.ADOQuery1.Open;
result:=StrToFloat(dm.ADOQuery1.FieldByName('balance').Text);
dm.ADOQuery1.Free;
dm.Free;
end;//查询密码的函数。
//输入:用户名(string),IP卡号(string)
//输出:IP卡密码。(string)
function getCardPwd(userId:string;cardId:string):string;stdcall;
var
dm:TDatamodule1;
// conn:widestring;
begin
dm:=Tdatamodule1.Create(datamodule1);
//在下面写数据连接字
//dm.ADOConnection1.ConnectionString:=conn;
dm.ADOQuery1.Connection:=dm.ADOConnection1;
dm.ADOQuery1.Close;
dm.ADOQuery1.SQL.Clear;
//在下面写Transact SQL语句。
dm.ADOQuery1.SQL.Add('select * from ipInfo');
dm.ADOQuery1.Open;
result:=dm.ADOQuery1.FieldByName('ip_acco').Text;
dm.ADOQuery1.FreeInstance;
dm.ADOConnection1.FreeInstance;
dm.FreeInstance;end;
exports
getBalance,
getCardPwd;
begin
//CoInitialize(nil);
end.datamodule的源码:
unit Unit1;interfaceuses
Messages,Classes,DB,
Windows,ActiveX,ComObj,
SysUtils, ADODB;type
TDataModule1 = class(TDataModule)
ADOQuery1: TADOQuery;
ADOConnection1: TADOConnection;
procedure DataModuleCreate(Sender: TObject);
procedure DataModuleDestroy(Sender: TObject); private
{ Private declarations }
public
{ Public declarations } end;var
DataModule1: TDataModule1;
implementation{$R *.dfm}procedure TDataModule1.DataModuleCreate(Sender: TObject);
begin
CoInitialize(nil);
end;procedure TDataModule1.DataModuleDestroy(Sender: TObject);
begin
CoUnInitialize();
end;调用方的源码:
unit Unit1;interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons,ActiveX,ComObj;type
TForm1 = class(TForm)
BitBtn1: TBitBtn;
procedure BitBtn1Click(Sender: TObject); private
{ Private declarations }
public { Public declarations }
end;
TgetCardPwd=function(userId:string;cardId:string):string;stdcall;
var
Form1: TForm1;implementation
//function getBalance:integer;StdCall external 'saturn.dll';
//function getPassword(ipAccount:string):string;StdCall external 'saturn.dll';
{$R *.dfm}procedure getCardPwd;
var
AHandle:THandle;
getCardPwd:TgetCardPwd;
begin
try
AHandle:=LoadLibrary('saturn.dll');
if AHandle<>0 then
begin
@getCardPwd:=GetProcAddress(AHandle,'getCardPwd');
if @getCardPwd<>nil then
showmessage(getCardPwd('dd','dd')); //or 1;
end;finally
FreeLibrary(AHandle);
end;end;procedure TForm1.BitBtn1Click(Sender: TObject);
var
AHandle:THandle;
getCardPwd:TgetCardPwd;
begintry
AHandle:=LoadLibrary('saturn.dll');
if AHandle<>0 then
begin
@getCardPwd:=GetProcAddress(AHandle,'getCardPwd');
if @getCardPwd<>nil then
try
showmessage(getCardPwd('dd','dd'));
except
end;
end;
finally
FreeLibrary(AHandle);
end;end;
附上源码:
dll程序:
library saturn;uses
types,
Messages,
Windows,
comobj,
ComServ,
ActiveX,
SysUtils,
Classes,
DB,
Forms,
ADODB,
Unit1 in 'Unit1.pas' {DataModule1: TDataModule};//查询余额的函数。
//输入:用户名(string),用户的卡号(string),密码(string)
//输出:IP卡余额。类型:real
function getBalance(userId:string;cardId:string;cardPwd:string):real;stdCall;
var
dm:TDatamodule1;
begin
dm:=Tdatamodule1.Create(datamodule1);
//在下面写数据连接字。 dm.ADOConnection1.ConnectionString:='';
dm.ADOQuery1.Connection:=dm.ADOConnection1;
dm.ADOQuery1.Close;
dm.ADOQuery1.SQL.Clear;
//在下面写Transact SQL语句。
dm.ADOQuery1.SQL.Add(''); dm.ADOQuery1.Open;
result:=StrToFloat(dm.ADOQuery1.FieldByName('balance').Text);
dm.ADOQuery1.Free;
dm.Free;
end;//查询密码的函数。
//输入:用户名(string),IP卡号(string)
//输出:IP卡密码。(string)
function getCardPwd(userId:string;cardId:string):string;stdcall;
var
dm:TDatamodule1;
// conn:widestring;
begin
dm:=Tdatamodule1.Create(datamodule1);
//在下面写数据连接字
//dm.ADOConnection1.ConnectionString:=conn;
dm.ADOQuery1.Connection:=dm.ADOConnection1;
dm.ADOQuery1.Close;
dm.ADOQuery1.SQL.Clear;
//在下面写Transact SQL语句。
dm.ADOQuery1.SQL.Add('select * from ipInfo');
dm.ADOQuery1.Open;
result:=dm.ADOQuery1.FieldByName('ip_acco').Text;
dm.ADOQuery1.FreeInstance;
dm.ADOConnection1.FreeInstance;
dm.FreeInstance;end;
exports
getBalance,
getCardPwd;
begin
//CoInitialize(nil);
end.datamodule的源码:
unit Unit1;interfaceuses
Messages,Classes,DB,
Windows,ActiveX,ComObj,
SysUtils, ADODB;type
TDataModule1 = class(TDataModule)
ADOQuery1: TADOQuery;
ADOConnection1: TADOConnection;
procedure DataModuleCreate(Sender: TObject);
procedure DataModuleDestroy(Sender: TObject); private
{ Private declarations }
public
{ Public declarations } end;var
DataModule1: TDataModule1;
implementation{$R *.dfm}procedure TDataModule1.DataModuleCreate(Sender: TObject);
begin
CoInitialize(nil);
end;procedure TDataModule1.DataModuleDestroy(Sender: TObject);
begin
CoUnInitialize();
end;调用方的源码:
unit Unit1;interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons,ActiveX,ComObj;type
TForm1 = class(TForm)
BitBtn1: TBitBtn;
procedure BitBtn1Click(Sender: TObject); private
{ Private declarations }
public { Public declarations }
end;
TgetCardPwd=function(userId:string;cardId:string):string;stdcall;
var
Form1: TForm1;implementation
//function getBalance:integer;StdCall external 'saturn.dll';
//function getPassword(ipAccount:string):string;StdCall external 'saturn.dll';
{$R *.dfm}procedure getCardPwd;
var
AHandle:THandle;
getCardPwd:TgetCardPwd;
begin
try
AHandle:=LoadLibrary('saturn.dll');
if AHandle<>0 then
begin
@getCardPwd:=GetProcAddress(AHandle,'getCardPwd');
if @getCardPwd<>nil then
showmessage(getCardPwd('dd','dd')); //or 1;
end;finally
FreeLibrary(AHandle);
end;end;procedure TForm1.BitBtn1Click(Sender: TObject);
var
AHandle:THandle;
getCardPwd:TgetCardPwd;
begintry
AHandle:=LoadLibrary('saturn.dll');
if AHandle<>0 then
begin
@getCardPwd:=GetProcAddress(AHandle,'getCardPwd');
if @getCardPwd<>nil then
try
showmessage(getCardPwd('dd','dd'));
except
end;
end;
finally
FreeLibrary(AHandle);
end;end;
Initialization
CoInitialize(nil);
Finalization
CoUnInitialize;因为你使用了ADO的组件,它是com组件
总是出这种错误:
[Error] saturn.dpr(82): 'BEGIN' expected but 'INITIALIZATION' found
[Error] saturn.dpr(89): Record, object or class type required
[Error] saturn.dpr(91): 'END' expected but end of file found
CoInitialize(nil);
{ ÏÂÃæµÄÒ»¶¨Òª£¬ÓÃBDE¾Í²»ÒªÁË¡£}
Finalization
CoUnInitialize;end.