开源IDL到C++代码生成器指南

在现代软件开发中,原生代码工具的重要性日益降低,但某些情况下,仍然需要使用这些工具来生成代码。最近,使用的COleDispatchDriver代码生成器出现了问题,生成的代码甚至无法编译。幸运的是,早已为了工作需要编写了自己的代码生成器,这次问题促使完成了自2018年开始的开源版本的开发。

这个代码生成器的目标是:

  • 完美解析由OLE Viewer生成的IDL文件
  • 自动使用库名称作为命名空间
  • 将helpstring输出为库的注释
  • 生成枚举声明
  • 在函数中输出枚举名称(而不是long)
  • 当无法识别类型时,输出VARIANT而不是注释说函数无法支持
  • 尽可能输出真实类型而不是IDispatch
  • 支持COM事件代码生成

使用代码

首先,需要访问oleview.exe,可以在Windows SDK中找到它。例如,在机器上,EXE文件位于C:\Program Files (x86)\Windows Kits\10\bin\10.0.20348.0\\x64\oleview.exe。注意,可能需要以管理员身份运行命令regsvr32 iviewers.dll来注册iviewers.dll。

现在,在OLE Viewer中选择一个接口(例如,Microsoft XML),并查看IDL文件。使用Ctrl-A选择所有代码,然后粘贴到一个文本文件中,并保存为.idl扩展名。对于IDL中通过importlib命令导入的任何类型库(在本例中是stdole2.tlb),重复此过程。

现在可以运行idl2cpp exe在.idl文件上。例如:

idl2cpp XML.idl

如果没有使用开关运行,应该会收到一个文件解析OK的消息。要输出一些代码,可以选择:

  • /enums
  • /events_h
  • /events_cpp
  • /fwd_decls
  • /h
  • /cpp

注意这些开关是互斥的。最好先将枚举和前向声明输出到两个单独的文件中,然后创建头文件并#include这两个文件。例如:

idl2cpp XML.idl /enums > msxml2_enums.h idl2cpp XML.idl /fwd_decls > msxml2_fwd_decls.h idl2cpp XML.idl /h > msxml2.h

最后,可以输出cpp文件:

idl2cpp XML.idl /cpp > msxml2.cpp

输出

以下是可以预期的输出示例:

msxml2_enums.h

#pragma once // GENERATED CODE by idl2cpp 2022-06-19 13:26:24 namespace MSXML2 { // Schema Object Model Content Types enum class _SCHEMACONTENTTYPE { SCHEMACONTENTTYPE_EMPTY = 0, SCHEMACONTENTTYPE_TEXTONLY = 1, SCHEMACONTENTTYPE_ELEMENTONLY = 2, SCHEMACONTENTTYPE_MIXED = 3 }; ... }

msxml2_fwd_decls.h

#pragma once // GENERATED CODE by idl2cpp 2022-06-19 13:27:25 namespace MSXML2 { struct IXMLDOMNode; struct IXMLDOMNodeList; struct IXMLDOMNamedNodeMap; ... }

msxml2.h

#pragma once // GENERATED CODE by idl2cpp 2022-06-19 13:29:27 // http://support.microsoft.com/kb/134980 #pragma warning(push) #pragma warning(disable:4275) // Microsoft XML, v6.0 namespace MSXML2 { using DOMNodeType = tagDOMNodeType; using SCHEMACONTENTTYPE = _SCHEMACONTENTTYPE; using SCHEMADERIVATIONMETHOD = _SCHEMADERIVATIONMETHOD; using SCHEMAPROCESSCONTENTS = _SCHEMAPROCESSCONTENTS; using SCHEMATYPEVARIETY = _SCHEMATYPEVARIETY; using SCHEMAUSE = _SCHEMAUSE; using SCHEMAWHITESPACE = _SCHEMAWHITESPACE; using SERVERXMLHTTP_OPTION = _SERVERXMLHTTP_OPTION; using SOMITEMTYPE = _SOMITEMTYPE; using SXH_PROXY_SETTING = _SXH_PROXY_SETTING; using SXH_SERVER_CERT_OPTION = _SXH_SERVER_CERT_OPTION; using XHR_PROPERTY = _XHR_PROPERTY; // Core DOM node interface struct AFX_EXT_CLASS IXMLDOMNode : COleDispatchDriver { IXMLDOMNode() {} IXMLDOMNode(LPDISPATCH pDispatch) : COleDispatchDriver(pDispatch) {} IXMLDOMNode(const IXMLDOMNode& dispatchSrc) : COleDispatchDriver(dispatchSrc) {} CString GetnodeName(); VARIANT GetnodeValue(); void SetnodeValue(const VARIANT& newValue); ... }

msxml2.cpp

// GENERATED CODE by idl2cpp 2022-06-19 13:30:45 namespace MSXML2 { CString IXMLDOMNode::GetnodeName() { CString result{}; InvokeHelper(0x2, DISPATCH_PROPERTYGET, VT_BSTR, &result, nullptr); return result; } VARIANT IXMLDOMNode::GetnodeValue() { VARIANT result{}; InvokeHelper(0x3, DISPATCH_PROPERTYGET, VT_VARIANT, &result, nullptr); return result; } ... }

请注意,自动生成的头文件包含了msxml2_enums.h和msxml2_fwd.h的#include。生成的源文件也会自动包含msxml2.h。目前,/events_cpp生成器需要手动添加对应头文件的#include。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485