>我有这种情况:
- 两个C++应用程序,用于在运行时加载插件 DLL。
- 具有 CLR\CLI 支持的插件 DLL,引用托管 (C#) DLL。
- 托管 (C#) DLL。
它的顺序是这样的:
- 存储在app1目录中的第一个应用
- 存储在app2目录中的第二个应用程序
- 所有具有依赖项(CLR 和托管)的插件 DLL 都在插件目录中,它与 app1 和 app2 并行
问题是,如果托管 DLL 无法从插件 DLL 加载,除非它位于可执行目录(app1、app2)中。我真的更喜欢它位于插件目录中,因为从逻辑上讲,它应该从插件而不是从应用程序中使用,并且我想避免重复,插件目录不能作为应用程序的子目录定位,因为我有两个应用程序。
可以使用 .config 文件配置 .NET 应用程序以启用来自其他目录的程序集绑定,但同样,这是一个C++应用程序。 此外,我已经阅读了有关配置文件的信息,它写道它只能用于子目录。我引用:(来自此链接)
"专用路径 必需"属性。
指定应用程序基目录的子目录 可能包含程序集。用分号分隔每个子目录。
澄清一下:从插件运行其他 DLL 没有问题(插件目录位于 %PATH% 环境中),仅加载托管 DLL 时出现问题。
所以,我的问题是:如何使托管 DLL 从自定义目录运行,该目录不是可执行文件的子目录?
我正在寻找一个可行的解决方案,没有重复的文件或目录。
例:
C# (托管) DLL
using System;
namespace PrintSample
{
public class CPrintSample
{
void print()
{
Console.WriteLine("Hello");
}
}
}
CLR DLL(参考在预处理器中添加和CLR_PRINT_SAMPLE_EXPORT定义的 C# PrintSample)
clr_sample.h
#pragma once
#ifdef CLR_PRINT_SAMPLE_EXPORT
#define CLR_PS_API __declspec(dllexport)
#else
#define CLR_PS_API __declspec(dllimport)
#endif
class IPrintSample
{
public:
virtual void Print()=0;
};
CLR_PS_API IPrintSample* Factory();
clr_sample.cpp
#include <msclr/marshal.h>
#include <msclr/auto_gcroot.h>
#include "clr_sample.h"
using namespace System;
using namespace System::Runtime::InteropServices;
using namespace msclr::interop;
using namespace PrintSample;
class CClrPrintSample : public IPrintSample
{
msclr::auto_gcroot<PrintSample::CPrintSample^> bridge;
public:
CClrPrintSample ()
{
bridge = gcnew PrintSample::CPrintSample();
}
~CClrPrintSample ()
{
delete bridge;
GC::Collect();
}
void Print()
{
bridge->print();
}
};
IPrintSample* CLR_PS_API Factory()
{
return new CClrPrintSample();
}
C++(控制台应用)(与 CLR 项目链接)
#include "clr_sample.h"
int main()
{
IPrintSample* ps = Factory();
ps->Print();
delete ps;
return 0;
}
- 当所有二进制文件都位于同一目录中时,它可以工作。
- 当 CLR DLL 位于另一个目录(位于 PATH 中,但不是应用程序目录的子目录中)并在当前应用程序目录中管理时,它将起作用。
- 当 CLR 和托管都位于另一个目录中时,它不起作用。
您可以将插件的符号链接创建到 app1/plugins & app2/plugins。 但它仅在 NTFS 上可用。见 mklink.exe doc。
这是您可接受的解决方案吗?