插件规范

COM组件为了联合开发实现统一标准

统一虚表标准

  1.虚表函数数量:不要有虚析构

  2.虚表函数顺序:不要使用虚函数重载

  3.虚表数量:不能用多重继承(两个基类都有虚函数), 不能使用虚继承

TLB com ==> 统一接口的二进制标准

Int有的语言是两个字节,有的是四个字节。像这种模糊的类型定义都去掉了

一般int都用long代替   char* 用 BSTR  代替

Long是四个字节 任何语言中都有四个字节的类型

BSTR  字符串类型  结构为  len + 字符串 +

因为有的语言字符串是 len 加字符串, 有的是结尾,为了统一,用BSTR  类型定义  

一般指针指向字符串的位置,所以可以当char*使用。其他不一样的语言需要减个4字节

c语言转换方式

CString  ---》 BSTR

   CString str("Hello");

   BSTR bstr = str.AllocSysString();

BSTR  ---》 CString

CString str;

BSTR bstr = ::SysAllocString(OLESTR("Hello"));

str = bstr;

c++转换  _bstr_t 是一个类

_bstr_t  ---》 CString

CString str;

_bstr_t bstr("Hello");

bstr += "World";

str = (BSTR)bstr;

char *p = (char*)bstr;

CString  ---》 _bstr_t

CString str("hello");

_bstr_t bstr(str);

BSTR bstr2 = (BSTR)bstr;

加载dll两种方式

一种LoadLibrary 哪里需要的时候加载   将指定的模块加载到调用进程的地址空间中

一种#pragma comment  程序运行开始会编译

导出函数加上PRIVATE私有 导出函数就会不是你de函数名。防止dll劫持

因为使用函数查注册表,加载dll  导出类工厂,导出类代码基本上是一样的,所以封装了函数方便调用

Windows封装的两个函数

CoCreateInstance  产生工厂

CoGetClassObject产生对象

CComPtr<ISuperMath> ptr;  系统封装的智能指针

自己实现的如下代码:

  //1.查注册表

  char Guid[60];

  GUID2String(clsid, Guid);

  char Subkey[260];

  wsprintf(Subkey, "CLSID\{%s}\InprocServer32", Guid);

  char Path[MAX_PATH];

  LONG size;

  RegQueryValue(HKEY_CLASSES_ROOT, Subkey, Path, &size);

  //2.加载dll

  HRESULT hr;

  HMODULE hDll = LoadLibrary(Path);

  if (hDll == NULL)

    return S_FALSE;

  MY_GET_CLASS_OBJECT pfnGetClassObject = (MY_GET_CLASS_OBJECT)GetProcAddress(hDll, "DllGetClassObject");

  if (pfnGetClassObject == NULL)

return S_FALSE;

产生工厂

  hr = pfnGetClassObject(clsid, iid, ppObject);

  if (FAILED(hr))

return hr;

产生对象

  hr = pClassFactroy->CreateObject(iid, ppObject);

  if (FAILED(hr))

    return hr;

加载dll想要使用还需要包含头文件,为了使其他语言函数定义特别发明了一种语言只能写函数声明;

IDL是用来描述软件组件接口的一种计算机语言。

TLB(Translation Lookaside Buffer)转换检测缓冲区是一个内存管理单元,用于改进虚拟地址到物理地址转换速度的缓存。

首先需要在 idl文件中写函数声明,在通过midl转换成tlb文件

Midl 全称Microsoft Interface Definition Language,即接口定义语言。它是微软的一个产品,定义了客户程序与服务器程序之间的接口

Idl语言

Class  -》  interface Include -》 import

加入了[]属性描述  in 传入 out传出 retral 返回值   

文本类 注释//  或者/**/  文本外显示注释 [helpstring(“注释内容”)]

实例:

import "unknwn.idl";

[

object,

uuid(2729A764-828A-46c9-9E53-842EEAFB323D)

]

interface IMyString : IUnknown

{

[helpstring("初始化字符串")]

HRESULT InitData([in]BSTR bstrInit);

[helpstring("获取字符串")]

HRESULT GetData([out, retval]BSTR *pbstrResult);

[helpstring("获取字符串长度")]

HRESULT GetLength([out, retval]long *plLen);  

};

Object:是指定接口是COM接口的方法。

Uuid:这指定了接口的GUID,使接口被唯一的标示。

Helpstring:最大长度255字节

 coclass(组件自动化)

这个表达式描述一个组件对象模型(COM)的全球统一标识符和它支持的接口.

[attributes]

coclass classname {

   [attributes2] [interface | dispinterface] interfacename;

};
语法元素:

 attributes

  在coclass表达式中,uuid属性是必须的.这个uuid与在系统注册表中注册组件的CLSID是相同的.在本表达式的前面还接受 helpstring , helpcontext , version , licensed , control , hidden 与 appobject 属性,但不是必须的.想了解这些属性更多的细节,请看下一章.appobject 属性使 coclass 的函数和属性在整个类型库内有效.

 classname

在类型库中标识普通对象的名字.

 attributes2

interface或dispinterface的可选属性.source , default 与 restricted 属性可以被接受.

 interfacename

 用 interface 或 dispinterface 声明的接口.

备注

组件对象模型定义一个类作为一个实现,允许QueryInterface在接口集之间查询.

 

学如逆水行舟,不进则退。 博客园技术交流群 群 号:1073255314 (本群没人,刚刚建立 -_-!!! )
原文地址:https://www.cnblogs.com/Mj-NaijAm/p/13602547.html