首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CLR dll无法运行托管DLL,除非它位于exe目录(或其子目录)内。

CLR dll无法运行托管DLL,除非它位于exe目录(或其子目录)内。
EN

Stack Overflow用户
提问于 2018-05-16 13:05:34
回答 1查看 200关注 0票数 0

我有这样的情况:

  1. 两个在运行时加载插件DLL的C++应用程序。
  2. 支持CLR\CLI的插件DLL,并引用托管(C#) DLL。
  3. 托管(C#) DLL。

它是这样订购的:

  • 存储在app1 dir中的第一个应用程序
  • 第二个应用程序存储在app2 dir中。
  • 所有具有依赖项(CLR和managed)的插件DLL都位于 plugin dir中,该插件与app1和app2并行。

问题是,如果托管DLL无法从插件DLL加载,除非它位于可执行的dir (app1,app2)中。我非常希望它位于插件 dir中,因为从逻辑上讲,它应该从插件中使用,而不是从应用程序中使用,而且为了避免重复,插件目录不能作为应用程序的子目录,因为我有两个应用程序。

.NET应用程序可以配置一个.config文件,以启用来自其他目录的程序集绑定,但这还是一个C++应用程序。此外,我还读过有关配置文件的文章,它写到,它只能用于子目录。我引用:(从这个链接)

privatePath必需属性。 指定可能包含程序集的应用程序基目录的子目录。用分号分隔每个子目录。

澄清一下:我在插件中运行其他DLL(插件目录位于%PATH%环境中)没有问题,我只是加载托管DLL时遇到了问题。

因此,我的问题是:如何使托管DLL能够从自定义dir中运行,而这个dir不是可执行文件的子目录?

我正在寻找一个工作的解决方案,没有重复的文件或目录。

示例:

C# (托管) DLL

代码语言:javascript
复制
using System;
namespace PrintSample
{
  public class CPrintSample
  {
    void print()
    { 
      Console.WriteLine("Hello");
    } 
  }
}

CLR (参考在预处理器中定义的C# PrintSample添加和CLR_PRINT_SAMPLE_EXPORT )

clr_sample.h

代码语言:javascript
复制
#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

代码语言:javascript
复制
#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项目)

代码语言:javascript
复制
#include "clr_sample.h"
int main()
{
  IPrintSample* ps = Factory();
  ps->Print();
  delete ps;
  return 0;
}
  • 当所有二进制文件都在同一个dir中时,它可以工作。
  • 当CLR位于另一个dir (在路径中,而不是app的子目录)中并在当前的app dir中管理时,它可以工作。
  • 当两者,CLR和managed都在另一个dir中时,它就不工作了。
EN

回答 1

Stack Overflow用户

发布于 2022-02-16 08:07:19

您可以将plugins dir创建为app1/plugins & app2/plugins的符号链接。但它只能在NTFS上使用。见mklink.exe医生。

你能接受这个解决方案吗?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50371778

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档