如何在Dll中调用DataModule? 哪位高人可以指点一下? to : Shd, rester 到目前为止,整个Delphi世界只有你们二位知道

  • 主题发起人 主题发起人 zyx1122
  • 开始时间 开始时间
Z

zyx1122

Unregistered / Unconfirmed
GUEST, unregistred user!
如何在Dll中调用DataModule? 哪位高人可以指点一下? to : Shd, rester 到目前为止,整个Delphi世界只有你们二位知道如何解决此问题。你们可不可以解释的详细一些? 终于算是解决了. 如果大家也需要这样的要求可以看看, 我过几天才把他Close (70分)<br />我用delphi写了一个dll
希望在此dll中调用DataModule, 如何做到?
TDataModule.Create(AOwer TComponent)需要参数AOwer(TComponent)
而我在dll中写的类ICtlVehicle没有继承TComponent(设计要求), 我就无法创建一个TDataModule.
///////////////////////// ICtlVehicle.pas /////////////////////
unit ICtlVehicle;
interface
uses
classes;
type
ICtlVehicleInOut = class;
TCtlVehicleInOutClass = class of ICtlVehicleInOut;
// ICtlVehicleInOut = class(TComponent)
ICtlVehicleInOut = class
protected
public
// constructor Create(AOwner: TComponent);
override;
constructor Create;
virtual;
end;

// TCtlVehicleInOutClass = class of ICtlVehicleInOut;
implementation
{ ICtlVehicleInOut }
//constructor ICtlVehicleInOut.Create(AOwner: TComponent);
constructor ICtlVehicleInOut.Create;
begin
inherited;
end;

end.

///////////////////////// uImpCtlVehicle /////////////////////////////////
unit uImpCtlVehicle;
interface
uses
ICtlVehicle,
Classes,
SysUtils,
uDMC, {uDMC是一个DataModule, 文件是uDMC.pas}
Dialogs;
type
TCtlVehicleInOut = class(ICtlVehicleInOut)
private
m_dm : TdmClient;
public
// constructor Create(AOwner: TComponent);
override;
constructor Create;
override;
end;

implementation
{ TCtlVehicleInOut }
//constructor TCtlVehicleInOut.Create(AOwner: TComponent);
constructor TCtlVehicleInOut.Create;
begin
inherited;
//????如何创建DataModule??????
//m_dm := ????;
//如果用m_dm := TdmClient.Create(需要参数),但无参数
if (m_dm = nil) then
begin
ShowMessage('m_dm is null');
end;
end;

end.

////////////////////// uDMC.pas //////////////////////////
unit uDMC;
interface
uses
SysUtils, Classes, DB, DBClient, MConnect;
type
TdmClient = class(TDataModule)
conn: TDCOMConnection;
cdsVehicle: TClientDataSet;
dsVehicle: TDataSource;
cdsVehiclecard_no: TStringField;
cdsVehiclevehicle_no: TStringField;
cdsVehiclevehicle_type: TStringField;
cdsVehiclein_time: TDateTimeField;
cdsVehicleout_time: TDateTimeField;
cdsVehiclein_picture: TBlobField;
cdsVehicleout_picture: TBlobField;
function GetDataModule : TdmClient;
private
{ Private declarations }
public
end;

var
dmClient: TdmClient;
implementation
{$R *.dfm}
end.

 
你用Application.CreateForm!放心,dll中也可以用Application。或者传主程序的Application
到dll中。
 
我写的dll没有Application, 也没有Form
我是在C++中调用此dll.
看来你的方法不适合我的要求.
不过, 还是要谢谢你.
 
想办法实现:
TCtlVehicleInOut = class(TComponent,ICtlVehicleInOut)
随便问一句,你为什么要定义一个接口?在Delphi中如果不考虑多类继承,一般情况下没有必要使用接口。
 
to: hanyongjian
如果用class(TComponent,ICtlVehicleInOut)
那么constructor Create(AOwner: TComponent);
override;
则我在创建TCtlVehicleInOut时必须提供AOwner : TComponent
但我是在VC++中使用TCtlVehicleInOut,
我不知道在VC++中如何提供TComponent
 
帮忙 up 一下
 
to: hanyongjian
昨天我用class(TComponent,ICtlVehicleInOut)
编译出错, 提示需要接口
 
>>> //如果用m_dm := TdmClient.Create(需要参数),但无参数
m_dm := TdmClient.Create(nil);
|
如果你不自己释放m_dm,那么在此对象被释放时释放m_dm.因为你是
用的NIL,那么你要自己释放。具体做法是:
m_dm := TdmClient.Create(nil);
try
做你想做的。一般是连接数据库。
我经常把m_dm定义为全局变量,有一个函数创建DataModel并建立数据库连接;
另外一个函数断开数据库连接,并释放DataModel。本例中直接释放了。
finally
m_dm.free;
m_dm := nil;
end;
 
没有注意到ICtlVehicleInOut竟是个类,而不是接口。真不好意思。但为什么不用T开头而用I呢。
 
@_@
关注!
 
to:hanyongjian
用 I 开头表示Interface, 这是我的习惯.
 
摘自中文开发在线
//dll主程序
library erpsend;

uses
SysUtils,
Classes,
Forms,
msgdata in 'msgdata.pas' {data: TDataModule};
{$R *.res}
function msgsend(MsgNo:Integer;AccNo:String;sAccNo:String;sName:String;sDepNo:String;sDepName:String;SysName:String;msg:string):Integer;stdcall;
begin
try
//根據參數更新SQL server
with data.Tmsgdo
begin
append;
FieldByName('MsgNo').AsInteger:=MsgNo;
FieldByName('AccNo').AsString:=AccNo;
FieldByName('sAccNo').AsString:=sAccNo;
FieldByName('sName').AsString:=sName;
FieldByName('sDepNo').AsString:=sDepNo;
FieldByName('sDepName').AsString:=sDepName;
FieldByName('SysName').AsString:=SysName;
FieldByName('sMsgTxt').AsString:=msg;
FieldByName('sTime').AsString:=FormatDateTime('yyyy/mm/dd hh:mm',now);
post;
end;
msgsend:=1;//成功返回1
except
msgsend:=0;//失敗返回0
end;
end;

exports
msgsend INDEX 1;
begin
Application.CreateForm(TData, Data);//dll調用時自動初始化數據ado連接
end.

//數據模塊DataModule單元
unit msgdata;
interface
uses
SysUtils, Classes, DB, ADODB,Dialogs;
type
Tdata = class(TDataModule)
ADOCon: TADOConnection;
Tmsg: TADOTable;
procedure DataModuleCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
data: Tdata;
implementation
{$R *.dfm}
procedure Tdata.DataModuleCreate(Sender: TObject);
begin
try
with ADOCondo
//動態建立與sql server 連接
begin
ConnectionString:='Provider=SQLOLEDB.1;Persist Security Info=True;Initial Catalog=erpmsg;Data Source=bill';
{其中:erpmsg為資料庫名,bill為服務器名}
Open('erpuser','erp');
{其中:erpuser為用戶名,erp這密碼}
end;
tmsg.TableName:='msgtxt';
tmsg.active:=true;
{若此處讀取外部配置文件,如ini文件,可實現SQL主機、用戶、密碼等信息的靈活修改
}
except
SHOWMESSAGE('連接數據服務器失敗!');
end;
end;

end.



這樣就可以在一些對ado支持不好的語言如vfp等中實際ado數據連接與更新,避免了客戶端odbc設置,不過在用戶電腦上要設一下sql客戶端,最簡單的辦法是寫入如下注冊表信息:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/MSSQLServer/Client]
[HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/MSSQLServer/Client/ConnectTo]
"BILL"="DBMSSOCN,BILL,1433"
[HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/MSSQLServer/Client/DB-Lib]
[HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/MSSQLServer/Client/TDS]
"BILL"="7.0"
 
Thank you.
我下班回家试一试.
我想应该可以
 
将TDataModule.Create(AOwer TComponent)需要参数AOwer(TComponent)
写成
TDataModule.Create(Application)
 
to:ugvanxk
这段时间我一直在写DLL,
前两天终于学会了如何在VC, VB中使用delphi写的DLL.
我试了一下你教我的方法。
但在
begin
Application.CreateForm(TData, Data);//dll調用時自動初始化數據ado連接
end.
总出错。
应该是没有CreateInstance(...)
你可不可以给我再写一个客户端调用的代码? 多谢!
 
有时写程序常常在一些不是技术的技术问题上卡住.
只要按别人规定的去写就可以写出来.
如果不知道就不会, 知道了就会.
没有一点可以思考的地方.
象这个问题我真不知道delphi是怎么样规定的.
写COM时也是,好烦Microsoft.
 
我用“全问检索”看了好久也没有看到和我一样的问题。
难啊!
 
后退
顶部