Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为32位DLL编写COM/ATL包装的正确方式_C#_C++_Com_32bit 64bit_Atl - Fatal编程技术网

C# 为32位DLL编写COM/ATL包装的正确方式

C# 为32位DLL编写COM/ATL包装的正确方式,c#,c++,com,32bit-64bit,atl,C#,C++,Com,32bit 64bit,Atl,我有一个关于为32位DLL正确编写COM/ATL包装的问题 问题出在这里。正如我的其他一些问题所暗示的那样,我经常必须在一个大型代码库上执行编码工作,其中包括从不同供应商的myraid链接的库。我们的软件可以在各种机器上运行,在各种体系结构上运行。该代码主要是用C语言编写的,C++ C++语言链接或编译/链接,然后在必要时从C语言调用/调用(在我看来,比管理C++更容易实现)。 无论如何,一个这样的程序包含C#代码,它必须与几个64位DLL接口,而这些DLL的源代码是不可用的。此软件的目标主机均

我有一个关于为32位DLL正确编写COM/ATL包装的问题

问题出在这里。正如我的其他一些问题所暗示的那样,我经常必须在一个大型代码库上执行编码工作,其中包括从不同供应商的myraid链接的库。我们的软件可以在各种机器上运行,在各种体系结构上运行。该代码主要是用C语言编写的,C++ C++语言链接或编译/链接,然后在必要时从C语言调用/调用(在我看来,比管理C++更容易实现)。 无论如何,一个这样的程序包含C#代码,它必须与几个64位DLL接口,而这些DLL的源代码是不可用的。此软件的目标主机均为64位。没问题。因此,在任何CPU模式下运行的C#会自动生成64位(没有WoW),并且能够无缝地P/调用这些预编译的第三方64位DLL

有一个这样的DLL,我只能使用32位版本。无法获取此DLL的64位版本。我有1.)32位DLL,一个2.)头文件,其中包含函数导出(即#define EXP u declspec(dllexport)、EXP BOOL WINAPI DLL _函数(IN int myInt,OUT int*result)和3.)一个相应的32位lib文件

经过广泛的研究,我了解到,显然,COM/ATL是从64位进程访问32位DLL的正确方式。很明显,我在WoW下生成了一个32位COM进程,并与之交互。从体系结构的角度来看,这听起来不错,但我找不到任何教程或关于如何具体做到这一点的描述。我已经尝试过使用VisualStudio2010的ATL向导,但仍然不知道如何正确地做到这一点。有自动工具吗?有模板或教程吗?我保证我已经尽我所能搜索了整个网络,我只是想知道1)我是否以正确的方式处理了这个问题,或者2)你知道任何资源吗?或者3)有没有人有一些通用的IPC模板

从我所读到的内容来看,像这样的图像不匹配似乎是程序员的常见问题,但除了“使用COM/ATL”之外,我还没有找到任何详细的解释(或者至少是指向详细解释的指针)。我以前的一篇文章给出了一个回答,其中P/Invoke签名调用的问题非常详细,这令人惊讶——我想知道我们是否可以在这里开始一个“确定的”64/32位跨体系结构的讨论

谢谢

-卡达吉


编辑:我已经了解并理解了体系结构,但我想知道实现的细节。

您可以在几分钟内获得简约的ATL解决方案

逐步说明:

  • 创建空解决方案
  • 使用Visual Studio向导添加ATL项目。这将是C++、ATL项目、可执行exe——您需要exe,因为这将是一个独立的32位进程,托管您的32位代码
  • 在项目中,您添加了类ATL Simple Object,所有默认值都来自于此-您将拥有一个类(例如CFoo)以及IDispatch派生接口
    IFoo
  • IFoo
    接口添加方法,并在CFoo类中添加相应的实现,例如
    CFoo::Bar
  • C++部分完成后,构建并确保其已COM注册(可执行文件使用
    /regserver
    参数运行一次)
  • 添加C#项目,强制其位为
    x64
    ,将COM引用添加到上面步骤5构建的ATL COM服务器
  • 将[StatThread]添加到您的C#代码和C#中的呼叫栏-完成了 C#:

    C++IDL:

    [
        // ...
    ]
    interface IFoo : IDispatch
    {
        [id(1)] HRESULT Bar();
    };
    
    C++:

    64位C#代码启动32位COM EXE并通过调用Bar方法


    源代码:/。

    最终,您需要在32位进程中托管32位dll,并将数据封送至64位进程和从64位进程封送数据

    首先,我应该解释什么是COM和DCOM:

    组件对象模型 在C/C++/VB6/etc之上提供了一个约定,该约定通过定义的接口标准化了对象的调用和数据交换。它还有一个注册表,用于将对象的相关dll加载到进程中

    DCOM 介绍编组和代理的概念,在这里您调用接口,但它是一个代理,它将参数包装在一个命名管道上,然后推送到另一个进程,等待结果并解压缩响应。进程可以在不同的计算机上,甚至具有不同的处理器体系结构

    因此,您可以使用DCOM解决您的问题,但学习曲线非常大,而且对于您想要的东西来说,它几乎太强大了

    您需要查看所需的应用程序体系结构,以确定正确的解决方案,但我将介绍一些高级原则

    如果您创建一个32位.Net进程/服务来托管DLL,那么您可以研究多种技术中的一种,以便在64位和32位进程之间执行IPC。您需要决定是每个64位进程一个,还是每个系统一个,以及它的生命周期应该是什么。 然后,您需要找到一个方法来交换数据,并封送调用

    • WCF如果您希望每台机器有一个主机进程,并且有一个相对复杂的接口,那么它可能是一个不错的(但很复杂)赌注

    • JSON-RPC/HTTP可能是另一个更轻量级的解决方案,您需要注意这里的安全性

    • STDIO如果你能侥幸逃脱,就编写一个32位的命令行应用程序,然后通过STDIO传输数据,这很容易保护,并且具有某种类似unix的优雅


    这些解决方案的好处在于,您可以尽可能多地留在.Net领域,这将缩短学习曲线

    因此,这不是讨论的正确场所。COM可以做到这一点,但它不是唯一的进程外
    [
        // ...
    ]
    interface IFoo : IDispatch
    {
        [id(1)] HRESULT Bar();
    };
    
    // IFoo
        STDMETHOD(Bar)()
        {
            MessageBox(GetActiveWindow(), _T("Hello, 32-bit World!"),
                _T("Information"), MB_OK);
            return S_OK;
        }