C++ DLL 中的 C# 表单应用程序

Posted

技术标签:

【中文标题】C++ DLL 中的 C# 表单应用程序【英文标题】:C# Form Application in C++ DLL 【发布时间】:2017-01-13 21:39:56 【问题描述】:

我有一个用 C# 开发的 Windows 窗体应用程序来进行网络摄像头捕获。我需要从称为 Magic 的应用程序开发环境中调用此 C# 表单(不要问为什么)。

如果我只需要调用 .exe 就可以了,但由于复杂的原因,我不允许在生产环境中使用 .exe;因此,我需要一个可以加载到应用程序中的 DLL。我不能使用 C# DLL,因为它没有像 C++ 中那样的 .def 文件来公开它的功能(如果你能为我解决这个问题,那么就不需要再进一步了)。因此,我需要找到一种方法来创建 C++ 包装器,这将提供在应用程序和 C# windows 窗体/DLL 之间传递数据的能力。

我在这里读到的大部分内容都建议将其注册为 COM 对象,但我不能这样做,因为这将部署到 100 多台机器上,并且为每个单独的机器注册它不会与我们的系统管理员一起飞行。谁能帮忙提供一个指南或建议我应该开始调查哪条路线?我尝试了多种方法都失败了,我真的在这里寻求帮助和指导。

【问题讨论】:

tigerang.blogspot.in/2008/09/reverse-pinvoke.html 任何类型的消息传递都可以作为 COM 的替代方案;包括命名管道或套接字;尽管最好使用更高级别的东西,例如 ZeroMQ 或其他 *MQ 框架,或者甚至在您的 C# 应用程序中托管某种 SOAP 或 REST 服务端点。 【参考方案1】:

我对您的问题的理解是,您需要在从本机 C++ DLL 调用的托管 C# DLL 中显示一个表单。这是可以做到的,我在一些项目中使用过这个。我已经创建了一个快速的 C++ 控制台应用程序(相同的代码可以放在一个 DLL 中),项目源代码CallManagedFromNative。

另一个解决方案是创建一个可以捕获网络摄像头数据的本机 C++ 项目,例如使用 Microsoft Media Foundation,如果对此感兴趣,可以在 MediaFoundation 找到源代码。

还是回到原生 C++ 调用托管 C# 表单示例。

#include "stdafx.h"
#include <iostream>

#include "Base\NativeProxy.h"
#include "Base\Types.h"

using namespace Nequeo::System::Any;

int main()

    std::vector<boost::any> param;
    param.push_back(3);
    boost::any returnData;

    Nequeo::NativeProxy managedProxy(L"ClassLibraryManaged.dll", L"ClassLibraryManaged.Class1");
    managedProxy.executeManaged(L"OpenForm", param, returnData);

    int retFromCall = boost::any_cast<int>(returnData);
    std::cout << retFromCall;        
    return 0;

指定托管 DLL、命名空间和类名。现在调用一个传递参数和可选返回值的方法。托管DLL中的代码:

namespace ClassLibraryManaged

    public class Class1
    
        public Class1()  

        public int OpenForm(int a)
        
            TestForm form = new TestForm();
            form.ShowDialog();
            return a * a;
        
    

示例项目包含测试项目所需的所有包含、bin 和库,您唯一需要的是boost我为这个项目使用版本 161,您可以使用自己的构建,也可以下载我的从BoostBuild161构建

【讨论】:

您提供了有趣的代码,但我找不到您在哪里定义 COM 线程模型? WindowsForm GUI 组件只能从具有 STA 模型的进程中启动。 99.99% 打开表单的代码位于示例代码中。显示的代码只是简单的用法。 我的意思是在带有 GUI 的 C# exe 应用程序中必须编写 [STAThread] static void Main() 是的,你是对的,命名空间 ClassLibraryManaged 中的 Class1 是一个名为 ClassLibraryManaged.dll 的 C# DLL,而不是 EXE。上面的代码显示了如何从本地 C++ 控制台应用程序打开托管 DLL 中的 C# 表单。 要从 C++ 应用程序调用 C# 表单中的打开、保存和文件夹对话框,请在 C# 应用程序示例 code 中使用 [ComImport]

以上是关于C++ DLL 中的 C# 表单应用程序的主要内容,如果未能解决你的问题,请参考以下文章

在 C# WPF 或 Windows 窗体应用程序中使用 DirectX c++ DLL

从 C# 程序访问 C++ DLL 中的多个函数

C#如何静态调用C++中的方法(静态调用dll)

无法在 C# Windows 应用程序下写入 C++ dll 项目中的文件

创建 DLL 的编程语言:C++ 或 C#

在 C++ DLL 和 C# 类之间来回传递变量