【问题标题】:FileNotFoundException: Could not load file or assemblyFileNotFoundException:无法加载文件或程序集
【发布时间】:2014-06-25 16:57:07
【问题描述】:

我有一个从 C# 编译的 dll (Tracker.dll),需要在本机 C++ 中使用它。我已经解决了这个问题;因为我无法修改 C#,所以我正在编写一个托管 C++ 包装器并相应地导出类。对于(简化)示例:

TrackerWrapper.h

#pragma once

#include <memory>

class __declspec(dllexport) TrackerWrapper {
  public:
    TrackerWrapper();
    ~TrackerWrapper();
    void Track();
  private:
    struct Impl;
    std::unique_ptr<Impl> pimpl;
};

TrackerWrapper.cpp

#using "Tracker.dll"

#include "TrackerWrapper.h"
#include <msclr\auto_gcroot.h>

using namespace System::Runtime::InteropServices;

struct TrackerWrapper::Impl {
  msclr::auto_gcroot<Tracker^> tracker;

  Impl() : tracker(gcnew Tracker()) {}
  ~Impl() {}
};

TrackerWrapper::TrackerWrapper() : pimpl(new Impl()) {}
TrackerWrapper::~TrackerWrapper() {}

void TrackerWrapper::Track() {
  pimpl->tracker->Track();
}

Main.cpp

#include "TrackerWrapper.h"
int main() {
  TrackerWrapper tracker;
  tracker->Track();
  return 0;
}

只要所有的对象和二进制文件在同一个目录下,编译后使用

cl /clr /LD TrackerWrapper.cpp
cl Main.cpp TrackerWrapper.lib,

一切运行完美。但是,理想情况下,我们需要将 Tracker.dll 以及 TrackerWrapper.libTrackerWrapper.dll 放在单独的目录中,例如垃圾箱。

因此,目录结构可能如下所示:

bin\
  Tracker.dll
  TrackerWrapper.dll
  TrackerWrapper.lib
  <other objects>

Main.cpp
TrackerWrapper.h
TrackerWrapper.cpp

我可以通过将bin 添加到我的%PATH%%LIB%%LIBPATH% 环境变量(或在编译时通过/link/AI 在命令行上)来编译所有内容,但是当我执行生成的可执行文件我收到以下错误:

Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'Tracker, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
  at TrackerWrapper.Impl.{ctor}(Impl* )
  at TrackerWrapper.{ctor}(TrackerWrapper* )

我尝试将#using "Tracker.dll" 更改为相对路径和绝对路径,但我遇到了同样的问题。

有什么想法吗?

【问题讨论】:

  • 你检查过Tracker.dll的依赖吗?
  • 除了典型的 .NET 依赖项之外,没有其他的了。

标签: c# c++ visual-studio-2012 dll


【解决方案1】:

你可以尝试两件事:

  1. 检查FileNotFoundException是否有内部异常,如果有, 它可能会为您提供详细信息。
  2. 从系统内部用process monitor监控进程,它可以记录进程的所有文件活动,从日志中,你可以知道哪个文件丢失了。请记住将过滤器设置为仅监控您的进程,否则它将监控所有进程。

【讨论】:

    【解决方案2】:

    您的库由 .net 基础架构加载,默认情况下仅在应用目录或 GAC 中搜索。

    如果您的应用程序是 .net,那么您可以在 App.config 中指定库路径,但由于您的应用程序是本机的,因此不知道混合 dll 是否会加载 App.config,您可以尝试一下。

    来自MSDN

    您可以在应用程序配置中使用 元素 文件以指定运行时在定位时应搜索的子目录 一个程序集。

    如果这不起作用,那么您的最后一个选择是将库添加到 GAC,但库不会真正位于指定的文件夹中,而是复制到 GAC 的文件夹中。

    【讨论】:

      猜你喜欢
      • 2020-04-22
      • 1970-01-01
      • 2019-12-22
      • 2023-04-07
      • 2011-09-29
      • 1970-01-01
      • 2023-01-17
      • 1970-01-01
      • 2020-08-17
      相关资源
      最近更新 更多