【问题标题】:Managed C++ with .NET Core 2.1使用 .NET Core 2.1 托管 C++
【发布时间】:2018-08-21 23:57:27
【问题描述】:

我们有一个用 C++ 编写的库。为了使其与我们更现代的 .NET 项目更兼容,我们将这个 C++ 库包装在另一个 .NET 项目中。从完整的 .NET Framework 项目(4.5、4.6 等)引用它时,它可以正常工作。

我正在使用 .NET Core 2.1 创建一个新应用程序,并尝试引用这个“包装在 .NET C++ 库中”。在我第一次尝试时,它说无法加载程序集失败。我通过安装 .NET Core SDK x86 并强制我的应用程序使用 x86 而不是 Any CPU 解决了这个问题。

我没有收到任何构建错误,但是当我尝试在此库中实例化一个类时,我收到以下异常:

<CrtImplementationDetails>.ModuleLoadException: The C++ module failed to load.
 ---> System.EntryPointNotFoundException: A library name must be specified in a DllImport attribute applied to non-IJW methods.
   at _getFiberPtrId()
   at <CrtImplementationDetails>.LanguageSupport._Initialize(LanguageSupport* )
   at <CrtImplementationDetails>.LanguageSupport.Initialize(LanguageSupport* )
   --- End of inner exception stack trace ---
   at <CrtImplementationDetails>.ThrowModuleLoadException(String errorMessage, Exception innerException)
   at <CrtImplementationDetails>.LanguageSupport.Initialize(LanguageSupport* )
   at .cctor()

.NET Core 2.1 是否完全支持这种情况?

【问题讨论】:

  • 包装项目的 .NET 版本是什么?
  • 嗨@ahelwer,它是.NET 4.0
  • 顺便说一句,我们也尝试使用 .NET 4.6,但它返回了相同的错误。
  • 要明确 - 这个包装项目是使用 PInvoke 调用本机库的 .NET 项目,还是 C++/CLI 项目(又名“托管 C++”)?
  • 正确,正如其他人回答的那样,.NET Core 不支持 C++/CLI,尽管 PInvoke 工作正常,正如您发现的那样。

标签: c# c++ .net asp.net-core .net-core


【解决方案1】:

正如其他人指出的那样,.NET Core does not currently support C++/CLI(又名“托管 C++”)。如果您想在 .NET Core 中调用本机程序集,则必须使用 PInvoke(如您所见)。

您也可以在 AnyCPU 中编译您的 .NET Core 项目,只要您保留 32 位和 64 位版本的本地库并在您的 PInvoke 调用周围添加特殊的分支逻辑:

using System;

public static class NativeMethods
{
    public static Boolean ValidateAdminUser(String username, String password)
    {
        if (Environment.Is64BitProcess)
        {
            return NativeMethods64.ValidateAdminUser(username, password);
        }
        else
        {
            return NativeMethods32.ValidateAdminUser(username, password);
        }
    }

    private static class NativeMethods64
    {
        [DllImport("MyLibrary.amd64.dll", EntryPoint = "ValidateAdminUser", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        public static extern Boolean ValidateAdminUser(String username, String password);
    }

    private static class NativeMethods32
    {
        [DllImport("MyLibrary.x86.dll", EntryPoint = "ValidateAdminUser", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        public static extern Boolean ValidateAdminUser(String username, String password);
    }
}

您的 MyLibrary.amd64.dll 和 MyLibrary.x86.dll 程序集位于同一目录中。如果您可以将相对路径放入 DllImport 并具有 x86/amd64 子目录,那就太好了,但我还没有弄清楚该怎么做。

【讨论】:

    【解决方案2】:

    不,它没有。 .NET 核心是跨平台的,但 C++/CLI 不是,Microsoft C++ 编译器需要 Windows。

    【讨论】:

    【解决方案3】:

    PInvoke 似乎是唯一的出路。

    将库 DLL 放在解决方案文件夹中(实际的 C++ DLL,而不是 .NET 包装器)。

    注意:不要在解决方案中引用 DLL,只需将 DLL 放在同一个文件夹中即可。

    然后使用 DLL Import 来访问方法:

    static class NativeMethods
    {
        [DllImport("MyLibrary.dll", EntryPoint = "ValidateAdminUser", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        public static extern Boolean ValidateAdminUser(String username, String password);
    }
    

    注意 2: 它仍然需要 .NET Core 项目才能在 x86 架构中运行。

    【讨论】:

      猜你喜欢
      • 2019-04-13
      • 2018-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-18
      • 1970-01-01
      • 2018-12-25
      相关资源
      最近更新 更多