#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:
Две вещи, которые вы можете попробовать:
- Проверьте, есть ли внутреннее исключение в FileNotFoundException, если есть, это может дать вам подробную информацию.
- Отслеживайте процесс с помощью process monitor из внутренней системы, он может регистрировать всю файловую активность процесса, из журнала вы можете определить, какой файл отсутствует. Не забудьте установить фильтр только для мониторинга вашего процесса, в противном случае он будет отслеживать все процессы.
Ответ №2:
Ваша библиотека загружается инфраструктурой .net и по умолчанию выполняет поиск только в каталоге приложения или в GAC.
Если ваше приложение было .net, вы можете указать путь к библиотеке в App.config, но поскольку ваше приложение является родным, не знаю, загрузит ли смешанная dll App.config или нет, может быть, вы можете попробовать.
Из MSDN:
Вы можете использовать элемент < probing > в файле конфигурации приложения, чтобы указать подкаталоги, которые среда выполнения должна искать при поиске сборки.
Если это не сработает, то ваш последний вариант — добавить библиотеки в GAC, но библиотека на самом деле не будет находиться в указанной папке, а скопирована в папку GAC.