加载DLL的多个实例(C#/。NET) [英] Loading multiple instance of DLL (C#/.NET)

查看:158
本文介绍了加载DLL的多个实例(C#/。NET)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发C#/ .NET 3.5应用程序。我正在使用C中的legacy DLL,signals.dll。我使用P / Invoke从.NET包装器调用它。我正在调用2种类型的处理函数,类型为A和B.当我只调用一种类型的处理时,一切正常。当我将电话交给A和B处理时,数据结果被破坏。我相信dll,signals.dll正在使用C风格的全局变量,数据被破坏。



为了解决这个问题,我在磁盘上创建了2个副本的信号。 dll和signals2.dll然后我使用P / Invoke修改.NET包装器,将类型A处理直接引导到一个dll,将B处理类型转换为另一个实例。现在,所有的工作都很好。



然后我在论坛和解决方案上看到类似的问题。 (支持具有全局数据的插件DLL的多个实例)。
基本上,提出的解决方案是从代码中动态的,在磁盘上创建一个.dll的新实例(根据需要),并加载它并从中调用函数。代码的关键部分如下所示:

  private IntPtr dllHandle; 
string myDllPath = Path.Combine(dllDir,String.Format(mylib- {0} .dll,GetHashCode()));
File.Copy(origDllPath,myDllPath);
dllPath = myDllPath;
dllHandle = LoadLibrary(dllPath);
_getVersion = GetProcEntryDelegate< _getVersionDelegate>(dllHandle,GetVersion);

private delegate int _getVersionDelegate();
private readonly _getVersionDelegate _getVersion;

public int GetVersion()
{
return _getVersion();
}

私有静态D GetProcEntryDelegate< D>(IntPtr hModule,字符串名称)
其中D:class
{
IntPtr addr = _getProcAddress(hModule , 名称);
if(addr == IntPtr.Zero)
throw new Win32Exception();
返回Marshal.GetDelegateForFunctionPointer(addr,typeof(D))作为D;
}

我想到了什么,是否可以修改上述代码创建dll IN MEMORY的副本,而不是在磁盘上加载它。我认为只有IntPtr dllHandle需要被愚弄从内存获取价值,而不是从LoadLibrary获取价值。怎么做?

解决方案

没有什么只是关于它:) - 复杂和涉及



这是一个可能有帮助的链接 - 从内存中加载库/模块



而且,由于@Hans Passant表示我会阻止您这样做 - 即使可能对于某些场景,这是一个诱人的解决方案(但是我并不认为你真的需要诚实,很可能)。



它涉及处理便携式可执行格式 - 我怀疑该项目涵盖了所有需要完成的工作。



您可以尝试使用C ++ / CLI包装器 - 或导出 MemoryLoadLibrary 并尝试P /调用 - 但是怀疑这个工作很容易。


I am developing C#/.NET 3.5 application. I am using legacy dll written in C, signals.dll. I invoke it from a .NET wrapper using P/Invoke. I am calling 2 types of processing functions, type A and B. When I call only one type of processing, all works fine. When I interleave calls to A and B processing, data result is corrupted. I believe that dll, signals.dll is using C style global variables, and data gets corrupted.

To resolve that, I created 2 copies of dll on disk, signals.dll and signals2.dll. Then I modified .NET wrapper using P/Invoke to direct type A processing to one dll, type B processing to another instance. And now, all works fine.

Then I saw similar problem on forums and solution there. (Supporting multiple instances of a plugin DLL with global data ). Basically, that proposed solution is dynamic lay from code, creating a new instance of .dll on disk (based on need), and loads it and invokes functions from it. Key part of code looks like this:

private IntPtr dllHandle;
string myDllPath = Path.Combine(dllDir, String.Format("mylib-{0}.dll", GetHashCode()));
        File.Copy(origDllPath, myDllPath);
        dllPath = myDllPath;
        dllHandle = LoadLibrary(dllPath);
        _getVersion = GetProcEntryDelegate<_getVersionDelegate>(dllHandle, "GetVersion");

    private delegate int _getVersionDelegate();
    private readonly _getVersionDelegate _getVersion;

public int GetVersion()
    {
        return _getVersion();
    }

private static D GetProcEntryDelegate<D>(IntPtr hModule, string name)
        where D: class
    {
        IntPtr addr = _getProcAddress(hModule, name);
        if (addr == IntPtr.Zero)
            throw new Win32Exception();
        return Marshal.GetDelegateForFunctionPointer(addr, typeof(D)) as D;
    }

What is coming to my mind, would it be possible to modify above code to create copy of dll IN MEMORY, not on disk and load it from there. I think just that IntPtr dllHandle needs to be fooled into getting value from memory, not from LoadLibrary. How to do that?

解决方案

There is nothing just about it :) - it's far more complex and involving

Here is a link that might help - Load Library/Module from Memory

And as @Hans Passant said I'd discourage you to go that way - even though it may be a tempting solution for some scenarios (but I don't see that you really need that honestly, nice maybe).

It involves dealing with the portable executable format - and I doubt that project covers all that needs to be done.

You could try making your C++/CLI wrapper - or exporting the MemoryLoadLibrary and try P/Invoking - but I doubt that'd work easily.

这篇关于加载DLL的多个实例(C#/。NET)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆