为什么在使用 .NET 6.0 时会出现 EntryPointNotFoundException 错误,而在使用 4.7.1 时却不会?
Why do I get an EntryPointNotFoundException error when using .NET 6.0, but not when using 4.7.1?
我正在使用 C++ 创建 DLL 并使用 C# 导入它。我编译 DLL 没有问题,从 .NET 4.7.1 调用它时它工作正常。但是,当我尝试从 .NET 6.0 调用它时,出现 EntryPointNotFoundException
错误:
Unhandled exception. System.EntryPointNotFoundException:
Unable to find an entry point named 'E' in DLL 'test.dll'.
at Program.E(int a, int b)
at Program.Main(String[] args) in G:\C++\Test\Program.cs:line 6
Test.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<!--<TargetFramework>net4.7.1</TargetFramework>-->
<TargetFramework>net6.0</TargetFramework>
<OutputType>Exe</OutputType>
<Configuration>Debug</Configuration>
</PropertyGroup>
</Project>
Test.cpp
extern "C"__declspec(dllexport) int E(int a, int b)
{
return x + y;
}
Program.cs
public class Program
{
[DllImport("test.dll")] public static extern int E(int a, int b);
public static void Main(string [] args)
{
float r = E(11, 26);
System.Console.WriteLine(r);
}
}
我的编译器标志如下:
g++ -shared -o test.dll Test.cpp -Wl,--out-implib,test.dll
研究:
因为很明显这是 .NET 6 的问题,所以我使用 Google:
进行了一些特定的搜索
"Unable to find an entry point named" in DLL ".net 6.0" 8 个结果,0 个有效。
"Unable to find an entry point named" in DLL "net6.0" 10 个结果,0 个有效。
"Unable to find an entry point named" "net6.0" 47 个结果,0 个有效。
"Unable to find an entry point named" ".net 6.0" 9 个结果,0 个有效。
"Unable to find an entry point named" ".net 6" 1370 个结果,0 个有效。
"Unable to find an entry point named" " dot net 6" 3 个结果,0 个有效
我执行了其他几种搜索变体,none 其中 link 向 .NET 6 提供了任何 link 和此错误。
我也尝试过重新启动,使用第二台计算机,并在两台计算机上重新安装 .NET 6。
我也查看了 .NET 6 documentation,但我找不到发生这种情况的原因。
我可以使用您使用 Visual Studio 2022 描述的设置在本地重现该问题。
初步说明 1: 所有 .NET 东西的命名可能会非常混乱:“.NET”不是“.NET Framework”。而“.NET Core”就是“.NET”的前身。大致。见 documentation and or this post.
前言2:.NET Core和.NET中的主要程序代码驻留在一个dll文件中,需要使用dotnet myProject.dll
执行。从 .NET Core 3.0 开始,创建了一个额外的 exe 文件,它简单地包装了该命令。另一方面,.NET Framework 直接生成 exe 文件。比较例如 or this post.
您的问题:您的问题现在如下:首先,您通过 g++ 创建 test.dll
。然后构建 Test.csproj
文件,对于 .NET 6,该文件不仅会生成 Test.exe
,还会生成 Test.dll
。由于 Windows' 文件系统不区分大小写,因此构建 csproj 文件 会覆盖 您自己的 g++ test.dll
文件。因此,结果 Test.dll
是完全不同的东西。尝试执行 Test.exe
将尝试从 dll 中导入函数 E
,但由于 dll 已被替换,该函数已不存在。另一方面,如果在构建 csproj 后用 g++ test.dll
替换 Test.dll
会导致 Test.exe
不再工作(因为,如上所述,Test.exe
并不真正包含您的代码,而是调用 Test.dll
,它不再包含正确的 .NET 代码)。
另一方面,对于 .NET Framework,不会出现此问题,因为构建 Test.csproj
文件只会生成一个 Test.exe
而不会影响您的 g++ test.dll
。
解决方法:最简单的解决方法是给自己的g++生成的dll起个不同的名字,例如test2.dll
,并将其导入到 C# 项目中。或者为 C# 项目(或者更确切地说,它的输出)选择一个不同的名称。
另一种解决方案是发布您的 .NET 6 项目 self-contained,使其仅包含一个 exe 文件。查看 documentation or
或 post.
我正在使用 C++ 创建 DLL 并使用 C# 导入它。我编译 DLL 没有问题,从 .NET 4.7.1 调用它时它工作正常。但是,当我尝试从 .NET 6.0 调用它时,出现 EntryPointNotFoundException
错误:
Unhandled exception. System.EntryPointNotFoundException:
Unable to find an entry point named 'E' in DLL 'test.dll'.
at Program.E(int a, int b)
at Program.Main(String[] args) in G:\C++\Test\Program.cs:line 6
Test.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<!--<TargetFramework>net4.7.1</TargetFramework>-->
<TargetFramework>net6.0</TargetFramework>
<OutputType>Exe</OutputType>
<Configuration>Debug</Configuration>
</PropertyGroup>
</Project>
Test.cpp
extern "C"__declspec(dllexport) int E(int a, int b)
{
return x + y;
}
Program.cs
public class Program
{
[DllImport("test.dll")] public static extern int E(int a, int b);
public static void Main(string [] args)
{
float r = E(11, 26);
System.Console.WriteLine(r);
}
}
我的编译器标志如下:
g++ -shared -o test.dll Test.cpp -Wl,--out-implib,test.dll
研究:
因为很明显这是 .NET 6 的问题,所以我使用 Google:
进行了一些特定的搜索"Unable to find an entry point named" in DLL ".net 6.0" 8 个结果,0 个有效。
"Unable to find an entry point named" in DLL "net6.0" 10 个结果,0 个有效。
"Unable to find an entry point named" "net6.0" 47 个结果,0 个有效。
"Unable to find an entry point named" ".net 6.0" 9 个结果,0 个有效。
"Unable to find an entry point named" ".net 6" 1370 个结果,0 个有效。
"Unable to find an entry point named" " dot net 6" 3 个结果,0 个有效
我执行了其他几种搜索变体,none 其中 link 向 .NET 6 提供了任何 link 和此错误。
我也尝试过重新启动,使用第二台计算机,并在两台计算机上重新安装 .NET 6。
我也查看了 .NET 6 documentation,但我找不到发生这种情况的原因。
我可以使用您使用 Visual Studio 2022 描述的设置在本地重现该问题。
初步说明 1: 所有 .NET 东西的命名可能会非常混乱:“.NET”不是“.NET Framework”。而“.NET Core”就是“.NET”的前身。大致。见 documentation and
前言2:.NET Core和.NET中的主要程序代码驻留在一个dll文件中,需要使用dotnet myProject.dll
执行。从 .NET Core 3.0 开始,创建了一个额外的 exe 文件,它简单地包装了该命令。另一方面,.NET Framework 直接生成 exe 文件。比较例如
您的问题:您的问题现在如下:首先,您通过 g++ 创建 test.dll
。然后构建 Test.csproj
文件,对于 .NET 6,该文件不仅会生成 Test.exe
,还会生成 Test.dll
。由于 Windows' 文件系统不区分大小写,因此构建 csproj 文件 会覆盖 您自己的 g++ test.dll
文件。因此,结果 Test.dll
是完全不同的东西。尝试执行 Test.exe
将尝试从 dll 中导入函数 E
,但由于 dll 已被替换,该函数已不存在。另一方面,如果在构建 csproj 后用 g++ test.dll
替换 Test.dll
会导致 Test.exe
不再工作(因为,如上所述,Test.exe
并不真正包含您的代码,而是调用 Test.dll
,它不再包含正确的 .NET 代码)。
另一方面,对于 .NET Framework,不会出现此问题,因为构建 Test.csproj
文件只会生成一个 Test.exe
而不会影响您的 g++ test.dll
。
解决方法:最简单的解决方法是给自己的g++生成的dll起个不同的名字,例如test2.dll
,并将其导入到 C# 项目中。或者为 C# 项目(或者更确切地说,它的输出)选择一个不同的名称。
另一种解决方案是发布您的 .NET 6 项目 self-contained,使其仅包含一个 exe 文件。查看 documentation or