幕后:第 2 部分:C++ WinRT 组件 DLL 和 C# Metro 应用程序





0/5 (0投票)
C++ WinRT 组件 DLL 和 C# Metro 应用程序
在本篇文章中,我们已经开发了一个 C++ WinRT 组件 DLL 和 C#.NET 应用程序。
这里重要的点是 C# 应用程序通过 RCW 机制访问 C++ WinRT 组件。同一个应用程序也可以用 JavaScript 开发,并且可以使用我们开发的 C++ DLL。哇,是不是很酷?
为了理解新编程模型的简单性,我们在第一部分创建了一个 C++ WinRT 组件 DLL,这是编写 Windows Runtime 组件所需的所有代码。
请下载代码并解压文件。
#pragma once
using namespace Windows::Foundation;
namespace CppWinRTComponentDll
{
public ref class CalculatorSample sealed
{
public:
int Add(int x, int y);
int Sub(int x, int y);
int Mul(int x, int y);
};
}
在这个例子中,您会立即注意到一些不是标准 C++ 的关键字。Visual C++ 定义了一些组件扩展,在 Metro 风格的应用中,它们本质上是底层 COM 调用(用于创建和使用 Windows Runtime 类型)的语法糖。您通常在 public interface
中使用这些扩展,当您的代码通过 ABI 将 Windows Runtime 类型与 JavaScript、C#、Visual Basic(甚至另一个 C++ 模块)进行双向传递时。Visual C++ 在 Windows Runtime 类型和标准 C++ 类型之间提供了各种隐式转换。典型的模式是内部像往常一样使用标准 C++ 类型和库,并在 public interface
中转换为 Windows Runtime 类型。
那么 C++ 组件是如何被 .NET 应用程序调用的呢?当我们构建 CppWinRTComponentDll
项目时,会在输出窗口看到以下内容。注意高亮的 CppWinRTComponentDll.winmd
文本。这意味着编译器正在生成一个 windmd
类型的文件。
1>—— Build started: Project: CppWinRTComponentDll, Configuration: Debug Win32 ——
1> CppWinRTComponentDll.vcxproj ->
C:\Users\Kishore\Documents\Visual Studio 11\Projects\CppWinRTComponentDll With
CSharp App\Debug\CppWinRTComponentDll\CppWinRTComponentDll.winmd
1> LINK : C:\Users\kishore\Documents\Visual Studio 11\Projects\CppWinRTComponentDll
With CSharp App\Debug\CppWinRTComponentDll\CppWinRTComponentDll.dll not found or
not built by the last incremental link; performing full link
1> Creating library C:\Users\kishore\Documents\Visual Studio 11\Projects\CppWinRTComponentDll
With CSharp App\Debug\CppWinRTComponentDll\CppWinRTComponentDll.lib and object
C:\Users\kishore\Documents\Visual Studio 11\Projects\CppWinRTComponentDll With
CSharp App\Debug\CppWinRTComponentDll\CppWinRTComponentDll.exp
1> CppWinRTComponentDll.vcxproj -> C:\Users\kishore\Documents\Visual Studio 11\
Projects\CppWinRTComponentDll With CSharp App\Debug\CppWinRTComponentDll\CppWinRTComponentDll.dll
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
您可以在调试文件夹中注意到 CppWinRTComponentDll.winmd 文件(CppWinRTComponentDll
附带 CSharp App\Debug\CppWinRTComponentDll),如图 1 所示。
这个 WinMD 文件本质上是一个 CLI 元数据文件,可以用 ILDASM 打开,如图 2 所示。CppWinRTComponentDll
是通过 CppWinRTComponentDll.winmd 文件中的 API 元数据公开的。WinMD 文件的格式是 Ecma-335,这与 .NET Framework 使用的格式相同。它只是使用了 ECMA-335 文件格式标准和框架,仅此而已。底层的二进制契约使我们能够以自己选择的开发语言直接访问 CppWinRTComponentDll
API。通过静态语言(如 C#)和动态语言(如 JavaScript)都可以理解 CppWinRTComponentDll
API 的形状和结构。在 C# 应用程序(CSharpApplication
项目)中可以看到,JavaScript、C#、Visual Basic 和 C++ 都支持 IntelliSense。
这个 CppWinRTComponentDll.winmd 文件是由 C++ 编译器创建的,可以看作是一个跨语言的头文件,因为 C# 无法理解 C++ 头文件,JavaScript 也无法理解。所以我们需要一个所有语言都能理解的文件格式,那就是 .winmd 文件格式。尽管我们编写了一个 CalculatorSample
类,但编译器为我们做的是,它还创建了一个 interface __ICalculatorSamplePublicNonVirtuals
,如图 3 所示,这是用于与 calculator
类通信的 COM 接口。这将其添加到了公共接口中。
CppWinRTComponentDll.winmd 文件的清单如图 4 所示。
如图 5 所示,我们可以在 WinmD 文件中看到 Add
方法的签名。
.method public newslot abstract virtual instance int32
Add(int32 x,
int32 y) cil managed
{
} // end of method __ICalculatorSamplePublicNonVirtuals::Add
在 ILDASM 中,单击 .class interface private abstract
auto ansi windowsruntime
。GUID 属性。这就像指定接口的 GUID,如图 6 所示。这是组件的 GUID。
WinMD 文件不包含任何 IL。它就像一个头信息,以便其他语言能够理解。这使得 Projections 能够发生。calculator
本身就是一个 ref class
。CppWinRTComponentDll.CalculatorSample
类实现了 .__ICalculatorSamplePublicNonVirtuals
,并实现了 Add
、Sub
和 Mul
方法,如下面的图 7 所示。
请注意,WinRT 中的每个对象都是 ref
计数的。
关于在第一部分创建的 C++ WinRT 组件 DLL 的详细信息(MSDN):C++/CX (Component Extensions)
Visual Studio 11 中的 Visual C++ 有一个创建 Metro 风格应用和组件的新编程模型。新模型的主要特性之一是抽象二进制接口(ABI),它定义了一个用于跨语言通信的接口。在 Windows Developer Preview 中,原生 C++ 可以通过 ABI 与 JavaScript 和托管 .NET 语言 C# 和 Visual Basic 进行通信。这意味着您可以用原生 C++ 创建高性能组件,并直接从其他语言中消耗它们。这也意味着您可以在原生 C++ 中直接使用 Windows Runtime 类型,而无需像使用 .NET Framework 类型时那样进行互操作。
在底层,新的编程模型基于 COM 的更新版本,但使用此新模型的方式比旧式 COM 编程更简单、更自然。当您在原生 C++ 中创建可用的 Windows Runtime 组件或 Metro 风格应用时,您主要像在标准 C++ 中一样使用类和成员。JavaScript 或 .NET 代码使用 new(或 New)实例化您的对象,并且根据客户端语言的机制销毁对象。当原生 C++ 使用 Windows Runtime 对象时,销毁通过引用计数来处理。
下载代码并解压文件。
“通过致力于一个事业、一个计划或一个价值体系来培养乐观主义。您会感到自己在朝着一个有意义的方向发展,这将帮助您克服日常的挫折。”—— Robert Conroy 博士
注意:代码是使用 Windows 8 和 Visual Studio 2011 开发者预览版开发的,实际版本发布时可能会有所更改。