FileNotFoundException: не удалось загрузить файл или сборку

#c# #c #visual-studio-2012 #dll

#c# #c #visual-studio-2012 #dll

Вопрос:

У меня есть dll ( Tracker.dll ), скомпилированная из C #, и мне нужно использовать ее на родном 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 <msclrauto_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.lib и TrackerWrapper.dll находились в отдельном каталоге, например, bin .

Таким образом, структура каталогов может выглядеть следующим образом:

 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" как относительный, так и абсолютный путь, но у меня та же проблема.

Есть идеи?

Комментарии:

1. вы проверяли зависимости Tracker.dll ?

2. Нет ничего, кроме обычного. СЕТЕВЫЕ зависимости.

Ответ №1:

Две вещи, которые вы можете попробовать:

  1. Проверьте, есть ли внутреннее исключение в FileNotFoundException, если есть, это может дать вам подробную информацию.
  2. Отслеживайте процесс с помощью process monitor из внутренней системы, он может регистрировать всю файловую активность процесса, из журнала вы можете определить, какой файл отсутствует. Не забудьте установить фильтр только для мониторинга вашего процесса, в противном случае он будет отслеживать все процессы.

Ответ №2:

Ваша библиотека загружается инфраструктурой .net и по умолчанию выполняет поиск только в каталоге приложения или в GAC.

Если ваше приложение было .net, вы можете указать путь к библиотеке в App.config, но поскольку ваше приложение является родным, не знаю, загрузит ли смешанная dll App.config или нет, может быть, вы можете попробовать.

Из MSDN:

Вы можете использовать элемент < probing > в файле конфигурации приложения, чтобы указать подкаталоги, которые среда выполнения должна искать при поиске сборки.

Если это не сработает, то ваш последний вариант — добавить библиотеки в GAC, но библиотека на самом деле не будет находиться в указанной папке, а скопирована в папку GAC.