IDL与C++
一、IDL简介
接口采用IDL(接口定义语言)来描述。UNO使用UNO-IDL作为接口定义语言。IDL是个描述性语言(而非编程语言),描述对象实现的接口。在IDL里,你定义接口的名字,每个属性和方法的名字,等等。一旦创建了IDL文件,你就可以使用IDL编译器产生c++编程语言中的头文件。
1、描述接口
//IDL
interface XdrivingDirection
{
void turnLeft();
void turnRight();
}
2、描述服务
//IDL
service car
{
//exported interface
interface XdrivingDirection;
interface XaccelerationControl;
[attribute] float speed;
[attribute] float angle;
}
3、描述模块
//IDL
module my_module
{
interface XdrivingDirection
{...}
service car
{...}
...
}
方法可以带参数。每个参数必须有以[in][out][intou]开头的标志。
eg. void setCount( [in] long nCount);
接口可以(多)继承自基类接口。派生接口可以申明它自己的属性和方法。但基类的属性和方法不能被重定义。
attribute和property有且只有一个区别:存取方法。前者是通过set/get(AttributeName)方法来存取;后者是通过setPropertyValue(PropertyName,Any)。
DannyB的观点:服务只是一种组合方式...1、更多服务 2、接口(A service is just a way to group...1.more services 2.interfaces)
你总是可以知道有哪些可用的接口,只要你知道服务的名字-----仅查看API docs便可知。没有悬念。聚集的有效接口即服务自身的接口以及所有它包含的服务它们自身的接口...
一个具体的例子:
//IDL
service OfficeDocument
{
interface com::sun::star::frame::Xmodel;
....
[optional] interface XEventBroadcaster;
[property,optional] boolean AutomaticControlFocus;
....
}
service TextDocument
{
service com::sun::star::document::OfficeDocument;
interface com::sun::star::text::XTextDocument;
...
}
//C++
Reference<XComponent> xWriterComponent=rComponentLoader->loadComponentFromURL(sDocUrl,OUString::createFromAscii("_blank"),0,Sequence<::com::sun::star::beans::PropertyValue>());
//xWriterComponent提供TextDocument服务和OfficeDocument服务
Reference<XTextDocument> xTextDocument(xWriterComponent,UNO_QUERY);
// XTextDocument是TextDocument服务的一个接口,XTextDocument.idl告诉了getText()方法但我们却并不知道有哪些可用的新服务。2种方法可以知道。其一是用reflection工具?
Reference<XText> xText = xTextDocument->getText();
Reference<XTextCursor> xTextCursor = xText->createTextCursor();//可用的服务有哪些?
二、IDL和C++
1、c++获取接口
c++里,你只能得到一个接口类型的变量。
//c++
using namespace com::sun::star::document; //使用名字空间
Reference<officeDocument> OfDoc=sth_to_get_this_service();//得到一个服务
//我想要查询XStorable接口,来保存我的文档。查询涉及3步:
//step1:从XStorable接口查询
Reference<XStorable> oToStore(OfDoc,UNO_QUERY);
//step2:包含声明里添加hpp文件,还添加相应的命名空间声明
#include <com/sun/star/frame/XStorable.hpp>
using namespace com::sun::star::frame;
//step3: makefile文件里添加相应的类型
#makefile
TYPES :=\
...
com.sun.star.frame.XStorable \
...
2、通过XMultiServiceFactory获取接口
如果相应的服务并非直接可用,你如何获取接口?
case1:接口方法允许获取新接口。这种情况下相应的idl文件不是必须的,且还没有发现不用reflection工具抽取新的可用服务的方法。
Reference<XTextDocument> xTextDocument (xWriterComponent,UNO_QUERY);
Reference<XModel> xModel(xTextDocument,UNO_QUERY);
(要包含XtextTable.hpp)
case2:没有接口方法可帮你。你必须在获取接口之前查询服务。
Reference<XTextDocument> xTextDocument (xWriterComponent,UNO_QUERY);
Reference<XMultiServiceFactory> oDocMSF(xTextDocument,UNO_QUERY);
Reference<XTextTable> xTable(oDocMSF->createInstance(OUString::createFromAscii("com.sun.star.text.TextTable")),UNO_QUERY);
(要包含的是XtextTable.hpp而非服务,因为你是通过createInstance()方法得到的。)
3、模块和接口映射
模块映射为名字空间
module mymodule{ struct E{long L;};};----->namespace mymodule{ struct E{long L;};}}
接口映射为包含由接口定义的类型、常量、操作和异常的公共定义c++类
//IDL
interface A{
struct S{ short field;}; };
--->
//c++
class SAL_NO_VTABLE A{
struct S { short field;};};//A
使用: A::S s;
s.field = 3;
//non-conformant uses,你不能申明 接口类的实例...指向接口类的指针...接口类的引用。
A a;
A *p;
void f(A &r);
(这是不是说只能通过查询,才能获取接口引用?)