使用.NET Core 2.1管理C ++

问题描述 投票:6回答:3

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

我正在使用.NET Core 2.1创建一个新的应用程序,我正在尝试引用这个“wrapped-in-.NET C ++库”。在我第一次尝试时,它无法说装配无法加载。我通过安装.NET Core SDK x86并强制我的应用程序使用x86而不是任何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是否支持这种情况?

c# c++ .net asp.net-core .net-core
3个回答
7
投票

正如其他人所指出的,.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(String username, String password);
        }
        else
        {
            return NativeMethods32.ValidateAdminUser(String username, String 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子目录,那将是很好的,但我还没弄清楚如何做到这一点。


5
投票

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


1
投票

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架构中运行。


推荐问答