当前位置:主页>仓库管理软件> 列表

在Midas中用多线程取数据的问题。如何用自己定义的接口取 找p3管理软件

进销存软件版1楼: 我要在另外一个线程中通过接口来取数据,参考了
http://www.delphibbs.com/delphibbs/dispq.asp?lid=2280814
的代码。
他第一步是
OleCheck(CoMarshalInterThreadInterfaceInStream(
IID_IAppServer,
FCDS.AppServer,
IStream(FStream)));
把接口放到一个指针中等待线程的调用。
但是我使用的接口是我自己定义的,于是我把IID_IAppServer改成我自己的接口的对应的GUID常量。但是执行到这里以后,它就提示说“不支持该接口”。
我应该怎么样做才能够调用我自己的接口来取数据?

在执行中取回接口,在线程中调用该接口。
在它的代码里面,运行到这句时第一次没有问题,第二次会产生一个地址读写错误。
OleCheck(CoGetInterfaceAndReleaseStream(IStream(FStream),
IID_IAppserver,
Appserver));
是什么原因造成?

2楼: 这个帖子供参考:
http://www.delphibbs.com/delphibbs/dispq.asp?lid=2901510 如p3管理软件

3楼: 谢谢Thx1180的提示。
CoMarshalInterThreadInterfaceInStream(IID_IAppServer, FCDS.AppServer,
IStream(FStream));
在上面的代码中,可以成功赋值 FStream;
但是我把IID_IAppServer改成我的中间成的接口IID_IKMServerItf的话。
FStream的值为Nil;
看来把ClientDataSet的Appserver属性赋值给他获取不到我的接口。
我是通过TSocketConnection来连接远程数据库的,尝试把该连接的Appserer传递进去也不行,FStream还是Nil值。
我应该怎么做才能够获得正确的值呢?

4楼: CoMarshalInterThreadInterfaceInStream
的第二个参数要求是一个接口类型,但是我能够获得的只是一个Variant。
我应该如何把一个Variant转换成一个接口类型?

5楼: 呵呵,好久没有弄这个了,当初写的测试代码也不知道丢到哪里去了:(

CoMarshalInterThreadInterfaceInStream的第一个参数和第二个参数是对应的;
//看来把ClientDataSet的Appserver属性赋值给他获取不到我的接口
看这句话似乎楼主想用这种方法获取接口?但是这个函数的作用是在线程之间传递接口指针用的啊

6楼: 对,现在的问题是这样的。
我对服务器层的接口进行了扩展,取数据的时候都是用扩展了的方法来获取的。
然后我连接服务器是用TSocketConnection,连上以后,我能够获得的不是一个接口,而是一个Variant。
但是CoMarshalInterThreadInterfaceInStream 函数只接受一个接口的指针类型。
我如何才能把这个Variant转换成一个指针类型呢?
我试过强行把那个Variant送到CoMarshalInterThreadInterfaceInStream 里面,提示说不支持该接口。

进销存软件版7楼: 翻了一下VCL的代码,找到了Variant转换到接口上的方法。
IDispatch(App).QueryInterface(IKMServerItf, IIII);
App 为从SocketConnection里面的Appserver
IKMServerItf 是我中间层的接口。
IIII 是一个指针
发现,App确实不能转换成我的接口IKMServerItf,但是可以转换成IAppserver。
但是为何App.MyFunction这样的调用又确实能够从我的中间层服务器上获得数据呢?
哎,搞不懂了。
大家救救我吧!!!
我应该怎么样做才能调用我自己定义的中间成的方法来获取数据,而不是调用IAppserver的方法。。。。。。。。。。。

8楼: 呵呵,其实Delphi的帮助里面都有说明了,贴出来你看看:

Calling server interfaces

Applications do not need to call the IAppServer interface directly because the appropriate calls are made automatically when you use the properties and methods of the client dataset. However, while it is not necessary to work directly with the IAppServer interface, you may have added your own extensions to the remote data module’s interface. When you extend the application server’s interface, you need a way to call those extensions using the connection created by your connection component. Unless you are using SOAP, you can do this using the AppServer property of the connection component. AppServer is a Variant that represents the application server’s interface. You can call an interface method using AppServer by writing a statement such as



MyConnection.AppServer.SpecialMethod(x,y);

However, this technique provides late (dynamic) binding of the interface call. That is, the SpecialMethod procedure call is not bound until runtime when the call is executed. Late binding is very flexible, but by using it you lose many benefits such as code insight and type checking. In addition, late binding is slower than early binding, because the compiler generates additional calls to the server to set up interface calls before they are invoked.
When you are using DCOM or CORBA as a communications protocol, you can use early binding of AppServer calls. Use the as operator to cast the AppServer variable to the IAppServer descendant you created when you
created the remote data module. For example:

with MyConnection.AppServer as IMyAppServer do

SpecialMethod(x,y);

To use early binding under DCOM, the server’s type library must be registered on the client machine. You can use TRegsvr.exe, which ships with Delphi to register the type library.



Note: See the TRegSvr demo (which provides the source for TRegsvr.exe) for an example of how to register the type library programmatically.

To use early binding with CORBA, you must add the _TLB unit that is generated by the type library editor to your project. To do this, add this unit to the uses clause of your unit.
When you are using TCP/IP or HTTP, you can’t use true early binding, but because the remote data module uses a dual interface, you can use the application server’s dispinterface to improve performance over simple late binding. The dispinterface has the same name as the remote data module’s interface, with the string ‘Disp’ appended. You can assign the AppServer property to a variable of this type to obtain the dispinterface. Thus:

var

TempInterface: IMyAppServerDisp;
begin
TempInterface :=IMyAppServerDisp(IDispatch(MyConnection.AppServer));
...
TempInterface.SpecialMethod(x,y);
...
end;

Note: To use the dispinterface, you must add the _TLB unit that is generated when you save the type library to the uses clause of your client module.


If you are using SOAP, you can’t use the AppServer property. Instead, you must use a remote interfaced object (THTTPRio) and make early-bound calls. As with all early-bound calls, the client application must know the application server’s interface declaration at compile time. You can add this to your client application either by adding the same unit the server uses to declare and register the interface to the client’s uses clause, or you can reference a WSDL document that describes the interface. For information on importing a WSDL document that describes the server interface, see Importing WSDL documents.

Note: The unit that declares the server interface must also register it with the invocation registry. For details on how to register invokable interfaces, see Defining invokable interfaces.

Once your application uses the server unit that declares and registers the interface, or you have imported a WSDL document to generate such a unit, create an instance of THTTPRio for the desired interface:

X := THTTPRio.Create(nil);

Next, assign the URL that your connection component uses to the remote interfaced object:

X.URL := SoapConnection1.URL;

You can then use the as operator to cast the instance of THTTPRio to the application server’s interface:

InterfaceVariable := X as IMyAppServer;

InterfaceVariable.SpecialMethod(x,y);

9楼: 问题解决了,哎,还是要好好看帮助。
谢谢thx1180的帮助。
原来接口要这样转换。
TempInterface :=IMyAppServerDisp(IDispatch(MyConnection.AppServer));
为何用这样的方法来获取我接口会有问题呢?
IDispatch(App).QueryInterface(IKMServerItf, IIII);

ok结贴放分了。