我强烈建议您创建一个IDL file 到design your COM interfaces。
鉴于您在回答中的示例,一个相当小的 IDL 文件可能是这样的:
import "oaidl.idl";
[object,
uuid(1f6efffc-0ac7-3221-8175-5272a09cea82),
dual,
oleautomation]
interface IStreamFrame : IDispatch {
[propget]
HRESULT Width([out, retval] long *pWidth);
[propget]
HRESULT Height([out, retval] long *pHeight);
[propget]
HRESULT Buffer([out, retval] SAFEARRAY(byte) *pBuffer);
};
[uuid(1f6efffc-0ac7-3221-8175-5272a09cea83)]
library ContosoStreamFrame {
importlib("stdole32.tlb");
interface IStreamFrame;
};
然后您使用midl.exe 生成带有 C/C++ 接口的 .h、用于 C/C++ 链接的 CLSID 和 IID 常量的 _i.c、用于 RPC 注册的 dlldata.c、带有代理的 _p.c和存根编组的东西和一个 .tlb ,它通常是 .idl 文件的解析表示。这在documentation 中有更好的描述。
编辑:似乎有no way to avoid the C/C++ file generation。
EDIT2:我刚刚找到了一种解决方法,使用nul 作为您不想要的输出文件。比如下面的命令只生成file.tlb:
midl.exe /header nul /iid nul /proxy nul /dlldata nul file.idl
注意:如果您的IStreamFrame 接口不打算跨进程使用,请将local 属性添加到接口。
在 C/C++ 中,您可以使用生成的特定文件,或 #import TLB 文件。在 .NET 中,您可以在 TLB 文件上运行 tlbimp.exe,这会生成一个 .NET 程序集。
如果您的项目以 .NET 为中心,您也可以使用 tlbexp.exe。但是,这将要求您了解 .NET COM 注释以及它们在 IDL 方面的含义,因此我不确定以牺牲大量装饰为代价以另一种语言保存一个额外的源文件是否有任何好处接口和类定义中的噪音。如果您希望在源代码级别完全控制类和接口,并且希望在 .NET 代码上尽可能简单(阅读、优化可用性和速度),这可能是一个不错的选择。
最后,您可以通过创建项目在 Visual Studio 中自动执行所有这些操作。如果您使用 IDL 方法,请添加调用 midl.exe 和 tlbimp.exe 的自定义构建步骤,并使依赖项目依赖此项目以获得正确的构建顺序。如果您使用 .NET 方法,请添加一个调用 tlbexp.exe 的自定义构建步骤,并使依赖的 C/C++ 项目依赖于该项目。
编辑:如果您不需要从 midl.exe 生成的 C/C++ 文件,您可以将 del 命令添加到特定输出文件的自定义构建步骤中。
EDIT2:或使用上述nul 解决方法。
当类型库已经存在时,一种常用的方法是使用 Visual Studio 将其导入 .NET。但这样一来,如果您更新 IDL 文件,您必须记住重新生成 TLB 并再次导入它。