【问题标题】:C++/CLI wrapper is working properly only on x86 machine, I need x64 machineC++/CLI 包装器只能在 x86 机器上正常工作,我需要 x64 机器
【发布时间】:2019-08-27 11:11:30
【问题描述】:

我有必须传递给 C# 项目的 x64 本机 C++ 库。 我基于this tutorial, 构建了 C++/CLI 包装器,一切正常。 但是,该项目仅在 x86 架构上编译。 当我尝试将本机 C++ 库添加到项目时,我收到了运行时错误。 项目不适用于 x64 架构,因为由于某些原因包装器需要 x86。另一方面,它不适用于 x86,因为该库需要 x64。

总的来说,我对 C++/CLI、包装器和 C# 的经验很少,而且我不知道如何解决这个问题。 尝试编译解决方案时,我收到 runetime 错误

System.BadImageFormatException: Could not load file or assembly 'Wrapper, Version=1.0.7178.20781, Culture=neutral, PublicKeyToken=null' or one of its dependencies. An attempt was ma
de to load a program with an incorrect format..

Link to error documentation

这是我的包装器

using namespace System;
namespace CLI {
    template<class T>
    public ref class Wrapper
    {
    protected:
        T* m_Instance;
    public:
        Wrapper(T* instance)
            :m_Instance(instance)
        {
        }
        virtual ~Wrapper()
        {
            if (m_Instance != nullptr)
            {
                delete m_Instance;
            }
        }
        !Wrapper()
        {
            if (m_Instance != nullptr)
            {
                delete m_Instance;
            }
        }
        T* GetInstance()
        {
            return m_Instance;
        }
    };
}

...这是一个使用此包装器的 C++/CLI 类

//**********************header file***********************

#include "Wrapper.h"
#include "../Core/Core.h"
using namespace System;
namespace CLI
{
    public ref class Model : public Wrapper<Core::Impl>
    {
    public:

        Model();
        bool test();
    };

//**********************Implementation******************************


#include "Model.h"

namespace CLI
{
    Model::Model()
        :Wrapper(new Core::Impl())
    {
        Console::WriteLine("Creating new Impl-wrapper object!!");
    }
    bool Model::test()
    {
        return m_Instance->test();
    }
}

它与我使用的教程几乎完全相同。

我不能修改那个原生 C++ 库,所以它必须在 x64 架构上工作。 您能否向我解释一下,为什么 wrapper 不想在 x64 上编译,但在 x86 上完美运行,有没有办法解决这个问题。完美的答案将提供一个适用于 x64 架构的 C++/CLI Wrapper 示例。 提前致谢

编辑, 哦,我忘了添加我的项目的属性。 操作系统为 Win10 (x64); .NET 目标框架 4.5.1;核心项目(最底层的项目,这里不做介绍)构建为静态.lib,Wrapper 是动态.dll。 VisualStudio 2017 v15.9.14

【问题讨论】:

  • 您必须获得原生 C++ 库的 x64 版本才能取得成功。与图书馆所有者交谈。
  • @HansPassant 库是 x64。由于某些原因,包装器仅在 x86 上构建。但我设法解决了“包装器问题”,现在它建立在与库相同的 x64 上。即使,在编译解决方案时,我仍然收到相同的运行时错误。

标签: c# c++ c++-cli 64-bit wrapper


【解决方案1】:

仔细检查您的项目设置,尤其是链接器。检查链接器的命令行选项卡。最近我在 Additional options 中遇到了野 X86 标志,这给了我类似的错误。

在高级中,检查目标机器

尝试为链接器和编译器启用详细输出,并检查是否出现任何 x86。

如果所有这些都被排除,请确保您的 lib 已真正编译并且有效,例如。通过依赖步行者。

【讨论】:

  • 好的,在这几个小时里我取得了一些进展。我的 Wrapper 现在可以在 x64 机器上正确编译,但前提是我没有在 Core 项目中包含该本地 C++ 库。如果我包含它,那么我有相同的运行时错误。现在,我今天的工作结束了,我要回家了,但明天一定会检查你的建议。
  • @MateuszBoruch 听起来您链接的库确实不适用于您的 DLL。尝试制作一个控制台应用程序而不是 DLL,看看它是否与外部 .lib 一起编译并实际做了一些事情。
  • 您的意思是创建 C++/CLI 控制台应用程序而不是 C++/CLI Wrapper?我用 C++ 控制台应用程序检查了它,它工作正常。
  • 仅作记录。我让它工作了。将平台和目标平台更改为 x64 后,我仍然收到该错误。问题是,我的核心项目使用的是 .pt 格式的外部文件。我显然将其添加到 Core 目录中。我不知道将该文件添加到 C# 目录也很重要。我在 C# 中调用该文件,但间接调用。仅通过调用 Core 项目一部分的另一个 void 函数的 void 函数。这是我认为我不需要将该文件添加到 C# 目录的方式。无论如何,它现在可以工作了,感谢您的帮助和建议:)
  • 也许吧。我认为,如果我在周末找到时间,我将创建一个 youtube 教程,其中将涵盖我在构建此解决方案时遇到的所有问题。如果我这样做了,我肯定会在这个主题的单独帖子中链接这个视频。让它工作起来很麻烦,我认为这个问题值得比现在更好地解决。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多