15

我已经搜索了很多网络和 StackOverflow,但似乎无法为我的以下问题找到明确的答案。

语境:

我希望移植一组用于 Windows Phone 8 (WP8) 平台的 C++ 帮助程序库。从历史上看,这些库是作为静态库(而不是 DLL)构建的。

我已经成功编写了特定于 WP8 的代码,因此这些库兼容并针对 ARM 构建,使用 WP8 可用的 API(使用 WP API 快速入门文档作为参考点)。由于必须用 WinRT 的 ThreadPool 替换经典的 Win32 线程调用,因此只有一个库(例如 Lib1)需要使用 WinRT 扩展(/ZW 标志)。

在构建 Lib1 时,我收到以下警告:警告 1 警告 LNK4264:将使用 /ZW 编译的目标文件归档到静态库中;请注意,在创作 Windows 运行时类型时,不建议与包含 Windows 运行时元数据的静态库链接。

— 搜索此警告时,我发现了这篇文章,指出:“如果您使用创建公共 ref 类、公共接口类或公共值类的静态库,链接器会引发此警告。您可以放心地忽略该警告如果静态库不会生成在库本身之外使用的 Windows 运行时组件。静态库中的公共组件将编译,但不会在运行时激活。任何旨在供其他组件或应用使用的 Windows 运行时组件必须在动态中实现-链接库(DLL)。”

在 Lib1 中,ClassA 包含使用 WinRT ThreadPool 调用的函数。ClassA 函数由 ClassB 调用,它们只是将常规 HANDLE 和 DWORD 返回给 ClassB。

代码示例:

// ClassA.cpp
HANDLE WINAPI ClassA::CreateThread(/* Params that are usually passed to Win32 CreateThread */)
{
    // Do WinRTThreadPool stuff to create WorkItem
    auto workItem = ref new Windows::System::Threading::WorkItemHandler([=](Windows::Foundation::IAsyncAction^)
    // More code that eventually results in a Win32 Handle

    return handle;
}

// ClassB.cpp
Handle handle = ClassA::CreateThread(/* Params that are usually passed to Win32 CreateThread */);

ClassA 的函数只能由 ClassB 从 Lib1 中调用,然后 ClassB 可以由链接 Lib1 的应用程序使用。

最后,对于我的问题:

  1. 使用 WinRT 扩展 (/ZW)的 C++ 库在构建为静态库时是否可以被 Windows Phone 8 应用程序使用?

  2. 使用 WinRT 扩展 (/ZW)的 C++ 库 (Lib1)在构建为静态库时是否可以被 Windows Phone 8 应用程序使用,尽管有警告?

  3. 如果两个问题的答案都是否定的,我是否必须为相应库中的所有类创建 WinRT 组件包装器,就像本文使用 Mandelbrot 算法演示的那样?还是我还缺少其他东西?

提前感谢您提供的任何意见。

4

1 回答 1

5

问题1 是的,只要您不使用手机上不允许使用的任何API,例如Win32、MFC 等。一些标准的c 功能对其有一些限制;例如,您只能在应用程序本地区域中的文件上调用 fopen。当然,您只能从 C++ 代码访问静态库中的功能。这个场景就是我喜欢称之为“Plain Old C++”的场景。它工作正常。

问题 2 是的,只要您在该静态库中定义的任何引用类仅打算在该静态库中使用。因此,在您的示例中,只要 A 类是常规的旧 C++ 类,就可以了。本质上,您不能拥有与 .NET 程序集中的公共类具有相同意义的公共 ref 类,因为这需要一些 COM-on-steroids 魔术,并且只会编译到 Windows 运行时组件中。如果你有普通的旧 C++ 代码,它包含对任何 ref 类代码的调用,并且使用你的静态库的代码以普通的旧 C++ 方式使用它,那么你很好。逻辑表明您将无法将 WinRT 类型从静态库中传递出去,尽管我还没有测试过这个假设。

问题 3 我相信您引用的文章忽略了静态库中的代码可以访问引用类等这一事实,所以不用担心,您不必围绕静态库编写 Windows 运行时组件包装器。如果您希望静态库中的代码通过“公共类”(在 .NET 程序集意义上)可用,您只想这样做。

要记住的是,您仍在为“Windows 商店”构建静态库。它是本机代码,但它仍然可以完成所有 C++/CX 的工作,它只是不包含 COM 激活内容,以允许在静态链接的 C++ 场景之外访问其中定义的类型。

于 2013-05-01T06:11:59.497 回答