为什么从 C# 控制台应用程序看到我的 C++ 程序集,而不是 ASP.NET 应用程序?

How comes my C++ assembly is seen from a C# console application but not an ASP.NET one?

我写了一个C++ dll。它有一个功能,returns double 1.0.

我试图在 C# 控制台应用程序中使用它:

namespace MyNameSpace
{

    class Program
        {
        [DllImport(@"C:\path\to\my\dll\myDll.dll")]
        static extern double SendOne();

        static void Main(string[] args)
        {
            double i = SendOne();
            Console.WriteLine(i);
        }
    }
}

这有效。

然后我尝试在一个 ASP.NET 应用程序中使用它,用一个空的 MVC 应用程序创建,然后添加一个控制器和一个视图:

Controllers/HomeController.cs:

{
    public class HomeController : Controller
    {
        [DllImport(@"C:\path\to\my\dll\myDll.dll")]
        static extern double SendOne();

        // GET: Home
        public ActionResult Index()
        {
            double i = SendOne();
            ViewBag["result"] = i;
            return View();
        }
    }
}

Views/Home/Index.cshtml:

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
</head>
<body>
    <div> 
        This is some text and the result : @{ ViewBag["result"]}
    </div>
</body>
</html>

这不起作用,returns BadImageFormatException。

在所有三个项目中,我手动将平台配置为 Debug / x64(来自默认的 Debug / AnyCPU)。

这是堆栈跟踪的底部:(从法语手动翻译的第一行)

[BadImageFormatException: Impossible charge the file or assembly '[Name of the ASP.NET Project]' or one of its dependencies. Attempt to load a program of incorrect format.]
System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks) +0
System.Reflection.RuntimeAssembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks) +36
System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks) +152
System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean forIntrospection) +77
System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection) +21
System.Reflection.Assembly.Load(String assemblyString) +28    System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String assemblyName, Boolean starDirective) +38

堆栈跟踪顶部:HttpException 0x80004005。

ASP.NET 项目和 C# 控制台应用程序都是同一个 Visual Studio 2017 解决方案中的两个项目,它们不相互引用并且我单独启动。

我不明白 ASP.NET 项目和 C# 控制台应用程序之间存在的差异,这些差异可能会导致本机 C++ Dll 加载在 C# 控制台应用程序中工作并在 ASP.NET 项目。

有人知道这个问题或对我可以尝试的方法有什么建议吗?谢谢。

BadImageFormatException 当程序尝试加载位数不匹配的模块时引发。帽子是 64,但进程尝试加载 32 位模块,反之亦然。因此, ASP 进程似乎是来自控制台应用程序的缓冲位数。

感谢@DavidHeffernan 的回答,我的研究让我想到了这个问题:Compile ASP.NET to 64 BIT

有替代答案可以解决我的问题:无论 ASP.NET 是编译为 32 位还是 64 位,调试器、IIS Express、以 32 位运行,这与使用 64 位 C++ dll 冲突。

需要更改调试器的版本,这可以在 Visual Studio -> Options -> Projects and Solutions -> Web Projects -> Use the 64 bits version of IIS Express for web sites and projects 完成。