我在做该书的第9张的时候遇到了以下的问题,请高手指教一下:1、为什么我在把provider.pas 和comobj.pas 文件拷贝到我的正在做的工程目录下,
然后编译时,会报一些不知是函数、还是过程、还是变量的,说是没有定义,比如:
没有定义 VarDispProc。这是怎么会事??
2、我调试了第9章的例子,发现只能查询,不能更新。
通过跟踪调试发现,更新的数据包无法正确上传,到了负责更新的协调对象那里就出错了,提示Project dllhost.exe raised exception class EOleError with message 'Variant does not //reference an automation object'. Process stopped. Use Step or Run to continue.下面结合代码介绍一下://第一步,客户端更新按钮代码发出更新指令,上传更新数据包
procedure TForm7.btnPubApplyClick(Sender: TObject);
var
uCoor : ImtsUpdateCoorObj;
vDatas : OleVariant;
iErrorCount : Longint;
begin
uCoor := ComtsUpdateCoorObj.CreateRemote('192.168.4.200');
uCoor.UpdatePublishers(cdsPublishers.Delta, 0, iErrorCount);//更新指令
end;
//第二步,负责更新的协调对象组件的代码,接受数据包cdsPublishers.Delta:
procedure TmtsUpdateCoorObj.UpdatePublishers(vDatas: OleVariant;
iMaxError: Integer; var iErrorCount: Integer);
begin
try
FMyDM.dcomcPublishers.AppServer.UpdateDatas(vDatas, iMaxError, iErrorCount);//调试到这一步出错,发现传递过来的数据包无法正确给Vdatas
SetComplete;
except
SetAbort;
end;
end;
//第二步提示的错误为:Project dllhost.exe raised exception class EOleError with message 'Variant does not reference an automation object'. Process stopped. Use Step or Run to continue.//第三步,最靠近数据库的COM+组件的代码,尚未执行到这一步。
procedure TmtsPublishers.UpdateDatas(vDatas: OleVariant;
iMaxErrors: Integer; var iErrorCount: Integer);
begin
try
// statements to try
dspPublishers.ApplyUpdates(vDatas, iMaxErrors, iErrorCount);
SetComplete;
except
SetAbort;
end; // try/except
end;
然后编译时,会报一些不知是函数、还是过程、还是变量的,说是没有定义,比如:
没有定义 VarDispProc。这是怎么会事??
2、我调试了第9章的例子,发现只能查询,不能更新。
通过跟踪调试发现,更新的数据包无法正确上传,到了负责更新的协调对象那里就出错了,提示Project dllhost.exe raised exception class EOleError with message 'Variant does not //reference an automation object'. Process stopped. Use Step or Run to continue.下面结合代码介绍一下://第一步,客户端更新按钮代码发出更新指令,上传更新数据包
procedure TForm7.btnPubApplyClick(Sender: TObject);
var
uCoor : ImtsUpdateCoorObj;
vDatas : OleVariant;
iErrorCount : Longint;
begin
uCoor := ComtsUpdateCoorObj.CreateRemote('192.168.4.200');
uCoor.UpdatePublishers(cdsPublishers.Delta, 0, iErrorCount);//更新指令
end;
//第二步,负责更新的协调对象组件的代码,接受数据包cdsPublishers.Delta:
procedure TmtsUpdateCoorObj.UpdatePublishers(vDatas: OleVariant;
iMaxError: Integer; var iErrorCount: Integer);
begin
try
FMyDM.dcomcPublishers.AppServer.UpdateDatas(vDatas, iMaxError, iErrorCount);//调试到这一步出错,发现传递过来的数据包无法正确给Vdatas
SetComplete;
except
SetAbort;
end;
end;
//第二步提示的错误为:Project dllhost.exe raised exception class EOleError with message 'Variant does not reference an automation object'. Process stopped. Use Step or Run to continue.//第三步,最靠近数据库的COM+组件的代码,尚未执行到这一步。
procedure TmtsPublishers.UpdateDatas(vDatas: OleVariant;
iMaxErrors: Integer; var iErrorCount: Integer);
begin
try
// statements to try
dspPublishers.ApplyUpdates(vDatas, iMaxErrors, iErrorCount);
SetComplete;
except
SetAbort;
end; // try/except
end;
就我做COM+的经验,感觉不要用李维的这种方法。书中实际上还说到另一更新方法。不用更改以上两个PAS文件。如果中间层要用DCOM的话可以用以下方法试试。
另一种方法一会儿发来。//更新函数
procedure TUpdateDCOM.Update(const strSql: WideString; vDatas: OleVariant;
IMaxError: Integer; var IErrorCount: Integer);
var
ServerProject:Iappserver; //保存类型的APPServer变量
OwnerData:olevariant;
begin
try
FMyDM.cdsUpdate.CommandText:=strSql; //取行字段(用返回记录数为0的SQL语句)
FMyDM.cdsUpdate.Data:=vDatas; //
ServerProject:=FMyDm.DCOMUpdate.GetServer; //取得对象句柄
ServerProject.AS_ApplyUpdates('dspUpdateDCOM',vDatas,IMaxError,IErrorCount,OwnerData);
if IErrorCount=0 then
SetComplete
else
SetAbort;
except
SetAbort;
end;
end;还有一种可能是:你的中间层普通数据模块要动态创建和释放。
加以下代码。
type
public
procedure Initialize; override;
Destructor Destroy; override;//释放数据模块
destructor TUpdateDCOM.Destroy;
begin
inherited;
FMyDM.Free;
end;
//建立数据模块
procedure TUpdateDCOM.Initialize;
begin
inherited;
FMyDM :=TDMUpdateDCOM.Create(Forms.Application);
end;
更新对象只放adoconnection,adodataset,datasetprovider并建立三者连接。provider.allowcommandtext设为true;协调对象中这样更新数据procedure TUpdate_AS.Update_AS(const strSql: WideString;
vDatas: OleVariant; IMaxError: Integer; var IErrorCount: Integer);
var
MyConn:IUpdate; //更新对象
OwnerData:OleVariant;
begin
try
OleCheck(ObjectContext.CreateInstance(CLASS_Update,IID_IUpdate,MyConn));
MyConn.AddSql(strSql); //中心对象方法。目的是使更新方法通用。详见下
MyConn.AS_ApplyUpdates('dspUpdate',vDatas,IMaxError,IErrorCount,OwnerData);
if IErrorCount=0 then
SetComplete
else
SetAbort;
except
SetAbort;
end;
end;//中心对象方法。目的是使更新方法通用。详见下
procedure TUpdate.AddSql(const strSql: WideString);
begin
adsUpdate.CommandText:=strSql;
end;同理,查询也推荐这种方法。