COM传递数据类型(类,对象)问题(100分)

  • 主题发起人 主题发起人 liao-li-jian
  • 开始时间 开始时间
L

liao-li-jian

Unregistered / Unconfirmed
GUEST, unregistred user!
如何在COM组件中传递自定义数据类型,比如类,对象等。
 
用OLEVARIANT以流方式传递对象
 
能否给一段提示性代码,谢谢
 
我也正在疑惑?,如何在客户端接收到服务器的对象参数,比如,数据模块,数据集,窗体等TOBJECT类型

对COM原理还没理解
 
你去看一下TMEMORYSTREAM,他有个方法WriteToStream,

function ComponentToVariant(AComponent: TComponent): OleVariant;
var
BinStream: TMemoryStream;
Data: Pointer;
begin
BinStream := TMemoryStream.Create;
try
BinStream.WriteComponent(AComponent);
result := VarArrayCreate([0, BinStream.Size-1], varByte);
Data := VarArrayLock(result);
try
Move(BinStream.Memory^, Data^, BinStream.Size);
finally
VarArrayUnlock(result);
end;
finally
BinStream.Free;
end;
end;

function VariantToComponent(AValue: OleVariant): TComponent;
var
BinStream: TMemoryStream;
Data: Pointer;
begin
BinStream := TMemoryStream.Create;
try
Data := VarArrayLock(AValue);
try
BinStream.WriteBuffer(Data^, VarArrayHighBound(AValue, 1)
+1);
finally
VarArrayUnlock(AValue);
end;
BinStream.Seek(0, soFromBeginning);
result := BinStream.ReadComponent(nil);
finally
BinStream.Free;
end;
end;
 
但是TComponent并不存在于利用com制作向导使用的类型库中,在接口函数中,提供的数据类型并没有Tobject,
我试了一下,如果不利用向导在可以直接调用。实例代码如下:
unit transdatatype;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,Db, ADODB,
StdCtrls, OleServer, xfSystemReg_TLB, Grids, DBGrids;

type
TForm1 = class(TForm)
Button1: TButton;
ADOQuery1: TADOQuery;
SystemReg1: TSystemReg;
DataSource1: TDataSource;
DBGrid1: TDBGrid;
Button2: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type
Imyinterface=interface
procedure draw(xx:Tadoquery;str:string);
end;
Tmyclass=class(TInterfacedobject,Imyinterface)
procedure draw(xx:Tadoquery;str:string);
end;
var
Form1: TForm1;

implementation

{$R *.DFM}
procedure Tmyclass.draw(xx:Tadoquery;str:string);
begin
with xx do
begin
close;
SQL.Clear;
SQL.Add(str);
open;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
ww:Imyinterface;
tempstr:string;
begin
ww:=Tmyclass.Create;
Adoquery1.ConnectionString:=SystemReg1.GetDBLoginString;
tempstr:='select * from geobookmark';
ww.draw(adoquery1,tempstr);
end;

end.
注意, xfSystemReg_TLB是通过注册标连接数据库的一个com
 
我也遇到类似的困惑,但我的想法是要传递自定义类型的对象(不是组件),如果用TStream来存取对象为OleVariant,该怎么进行?
 
我也有aladdin同样的问题,而且很急,望哪位大虾出手相助!
 
你要自己实现marshal。一句半句也说不清楚。找本书看吧。而且,你说的东西很多是
明显不能marshal的,因为com和dcom都可以利用同样的方法进行调用,就算你local可以
marshal,remote marshal也要完蛋,你想想,句柄、私有工作内存地址怎么marshal?

所以,简单的办法是传递generic数据。
 
那如果以我自己定义的类型来传递行不行?
 
怎么传递generic数据?
 
default的marshal就是bit-wise copy。你自己的类型也可以。我说的generic数据
指的是最基础的数据类型:bstr, int...
但是如果你的类型中包含了作用域相关的数据:内存地址,句柄……就不能使用
default marshal。
 
后退
顶部