繁体   English   中英

我可以使用 C++/WinRT 编写一个 DLL 以供 Windows 桌面应用程序(不是 UWP)或作为 Unity 插件使用吗?

[英]Can I write a DLL with C++/WinRT to be consumed by a windows desktop app(not UWP) or as a Unity plugin?

我已经尝试用 C++/WinRT 编写一个简单的 DLL。 它可以通过 Windows 桌面应用程序毫无问题地导入和运行(我尝试编写两个桌面应用程序,一个使用 C#,另一个使用 C++/WinRT。)

当我将它作为 Unity 的插件导入时,它运行良好,但会导致 Unity 在退出时冻结。 然后我将其缩小到一些可能的线程问题。 具体来说,如果插件在插件生成的线程上回调 Unity,则调用会通过,并且代码运行良好,但是当我尝试退出 Unity 编辑器时,它会冻结。

这是 DLL 的简短示例代码。 #include “stdafx.h”

#include <winrt\base.h>

extern "C"
{
    typedef void(*testCallback)(Info info);

    __declspec(dllexport) void TryAsyncWinRT(testCallback callback);
}

using namespace winrt;
using namespace Windows::Foundation;

static testCallback handler;

IAsyncAction JustDoWork()
{
    co_await winrt::resume_background();

    int result{};

    /*
    Some calculation...
    */

    if (handler) {
        handler(result);
    }

    co_return;
}

void TryAsyncWinRT(testCallback callback)
{
    handler = callback;
    JustDoWork();
}

我使用的编译器是 Visual Studio 2017,安装了 C++/WinRT 扩展。 我没有更改 Visual Studio 提供的“DllMain”中的任何内容。 我没有在 DLL 代码中调用“init_apartment()”,因为我认为这是由主机应用程序完成的,因为每个应用程序只能有一个多线程单元。

如果我不回调到 Unity,就没有问题。 如果我只使用标准库的线程实用程序,Unity 也可以正常工作。

void JustDoWork()
{
    int result{};

    /*
    Some calculation...
    */

    if (handler) {
        handler(result);
    }
}

void TryAsync(testCallback callback)
{
    handler = callback;
    std::thread(JustDoWork).detach();
}

我觉得我一定遗漏了一些东西,但我找不到任何关于如何使用 C++/WinRT 编写常规 DLL(不是 Windows 运行时组件)的文档。

任何善良的灵魂都可以发光吗? 非常感谢!

在尝试实现 BLE 时,我偶然发现了同样的问题。 具体来说,当我尝试在 C++ winrt dll 中调用 C# 回调时,我的 C# 程序崩溃了,而且当我在 C# 程序中使用 C++ winrt 分配的内存时,即使我尝试遵循内存分配建议,它也经常崩溃。

我最终完全避免了编组回调,并通过轮询函数实现了这些机制。 我还分配了 C# 端函数调用所需的所有内存。

对我来说,这感觉像是一种解决方法,但也感觉很安全。 您可以在此处查看我如何将回调转换为轮询的示例。

您必须在 exe 主线程(UI 线程)中释放 C++/WinRT DLL 的所有资源。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM