简体   繁体   English

使用 .NET Core 2.1 托管 C++

[英]Managed C++ with .NET Core 2.1

We have a library written in C++.我们有一个用 C++ 编写的库。 To make it more compatible with our more modern .NET projects, we wrapped this C++ library in another .NET project.为了使其与我们更现代的 .NET 项目更兼容,我们将这个 C++ 库包装在另一个 .NET 项目中。 It works fine when referencing it from full .NET Framework projects (4.5, 4.6, etc.).从完整的 .NET Framework 项目(4.5、4.6 等)中引用它时,它工作正常。

I am creating a new application using .NET Core 2.1 and I am trying to reference this "wrapped-in-.NET C++ library".我正在使用 .NET Core 2.1 创建一个新应用程序,并且我正在尝试引用这个“wrapped-in-.NET C++ 库”。 On my first attempt, it failed saying the assembly couldn't be loaded.在我第一次尝试时,它说无法加载程序集失败。 I fixed this problem by installing .NET Core SDK x86 and forcing my application to use x86 , not Any CPU .我通过安装 .NET Core SDK x86 并强制我的应用程序使用x86而不是Any CPU来解决这个问题。

I get no build errors, but when I try to instantiate a class within this library, I get the following exception:我没有遇到构建错误,但是当我尝试在此库中实例化一个类时,出现以下异常:

<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()

Does .NET Core 2.1 support this scenario at all? .NET Core 2.1 是否完全支持这种情况?

As others pointed out, .NET Core does not currently support C++/CLI (aka "managed C++").正如其他人指出的那样,.NET Core目前不支持 C++/CLI (又名“托管 C++”)。 If you want to call into native assemblies in .NET Core, you must usePInvoke (as you discovered).如果要调用 .NET Core 中的本机程序集,则必须使用PInvoke (如您所见)。

You can also compile your .NET Core project in AnyCPU, as long as you keep around both 32- & 64-bit versions your native library and add special branching logic around your PInvoke calls:您还可以在 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);
    }
}

Where you have your MyLibrary.amd64.dll and MyLibrary.x86.dll assemblies in the same directory.您的 MyLibrary.amd64.dll 和 MyLibrary.x86.dll 程序集位于同一目录中的位置。 It would be nice if you could put relative paths into DllImport and have x86/amd64 subdirectories, but I haven't figured out how to do that.如果您可以将相对路径放入 DllImport 并拥有 x86/amd64 子目录,那就太好了,但我还没有想出如何做到这一点。

No it does not.不,不是的。 .NET core is cross platform but C++/CLI is not, the Microsoft C++ compiler requires Windows. .NET 核心是跨平台的,但 C++/CLI 不是,Microsoft C++ 编译器需要 Windows。

PInvoke seems to be the only way to go. PInvoke似乎是唯一的出路。

Put the library DLL in the solution folder (the actual C++ DLL, not a .NET wrapper).将库 DLL 放在解决方案文件夹中(实际的 C++ DLL,而不是 .NET 包装器)。

NOTE: Don't reference the DLL in the solution, just place the DLL in the same folder.注意:不要在解决方案中引用 DLL,只需将 DLL 放在同一文件夹中。

Then use DLL Import to access the methods:然后使用DLL 导入来访问这些方法:

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

NOTE 2: It still requires the .NET Core project to run in x86 architecture.注意 2:它仍然需要 .NET Core 项目在 x86 架构中运行。

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

相关问题 异常:System.DllNotFoundException - 使用.NET Core 2.1调用CoolProp(本机C ++库)函数 - Exception: System.DllNotFoundException - Invoke CoolProp (Native C++ library) functions with .NET Core 2.1 当本机进程托管 Z303CB0EF9EDB9082D61BBBE5825D9 时,在 C# 和 C++ 之间传递 C# 托管实例 - passing C# managed instances between C# and C++ when native process is hosting the .NET Core runtime .Net Core 2.1中的传呼机 - Pager in .Net Core 2.1 C# .net core 2.1 授权的异常处理 - C# .net core 2.1 Exception handling of Authorization Asp.Net Core 2.1返回的C#SimpleJson和Json - C# SimpleJson with Json returned by Asp.Net Core 2.1 c#.Net Core 2.1 授权属性 - 默认声明 - c# .Net Core 2.1 Authorize Attribute - Default Claims 在 C# / .NET Core 2.1 应用程序中运行 Powershell 5.1 - Running Powershell 5.1 in a C# / .NET Core 2.1 Application 从Net Core 2.1 C#中的模板生成Word文档 - Generate word document from a template in Net Core 2.1 C # 使用 xUnit 框架模拟 C# Net Core 2.1 Function App - Mocking in C# Net Core 2.1 Function App with xUnit framework .NET Core 2.1和EF Framework 2.1 - .NET Core 2.1 and EF Framework 2.1
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM