问题(简化,以使事情更清楚):

    1.有一个静态地联静态的。lib,有一个函数增量:
    
        extern int CallCount = 0;
        int TheFunction()
        {
            void *p = &CallCount;
            printf("Function called");
            return CallCount++;
        }
    
    2.静态的。lib是联成一个管理C++/CLI managed.dll 包裹该函数将方法:
    
        int Managed::CallLibFunc()
        {
            return TheFunction();
        }
    
    3.测试的应用程序具有参考managed.dll 并创建了多个领域调用C++/CLI包装:
    
        static void Main(string[] args)
        {
            Managed c1 = new Managed();
            int val1 = c1.CallLibFunc();
            // value is zero
    
            AppDomain ad = AppDomain.CreateDomain("NewDomain");
            Managed c = ad.CreateInstanceAndUnwrap(a.FullName, typeof(Managed).FullName) as Managed;
            int val2 = c.CallLibFunc();
            // value is one 
        }
    

问题:

基于什么我读至关重要的。净Vol1CLR的盒子,我希望val2是零,因为一个全新的复制的管理。dll/静态的。lib装载时CreateInstanceAndUnwrap。我误解发生了什么事?静态图书馆似乎并不尊重程序域的界限,因为它不受管理的代码。有没有办法绕过这个问题比其他通过创建一个全新的工艺的实例,管理?

非常感谢大家!

有帮助吗?

解决方案

我的直觉是,正如你怀疑,非托管Dll被装载在下文的过程,而不是在上下文的程序域,因此任何静态的数据管理的代码之间进行共享应用程序域.

这个链接 有人表示同样的问题,你有,还不是100%核查,但很可能是这种情况。

这个链接 是关于建立一个回从不受管理的代码进入的一个程序域使用thunking伎俩。我不确定这可以帮助你但也许你会发现这很有用建立某种解决方法。

其他提示

之后你打电话

Managed c1 = new Managed(); 

你的managed.dll 包装物将载入主要的应用程序域的您应用程序。直到它会在那里域托管的东西从静态的。lib将与其他领域。而不是建立独立的过程中,你只是需要确保(在每个呼叫),managed.dll 未载入任何应用领域。

比较与

static void Main(string[] args)
{

    {       
                AppDomain ad = AppDomain.CreateDomain("NewDomain");
                Managed c = ad.CreateInstanceAndUnwrap(a.FullName, typeof(Managed).FullName) as Managed;
                int val2 = c.CallLibFunc();
                //  Value is zero

               AppDomain.Unload(ad)
    }
    {       
                AppDomain ad = AppDomain.CreateDomain("NewDomain");
                Managed c = ad.CreateInstanceAndUnwrap(a.FullName, typeof(Managed).FullName) as Managed;
                int val2 = c.CallLibFunc();
                //  I think value is zero

               AppDomain.Unload(ad)
    }


}
`

重要,并且:如果你只是添加一条线JIT编译器的负载managed.dll 和魔法消失。

static void Main(string[] args)
{

    {       
                AppDomain ad = AppDomain.CreateDomain("NewDomain");
                Managed c = ad.CreateInstanceAndUnwrap(a.FullName, typeof(Managed).FullName) as Managed;
                int val2 = c.CallLibFunc();
                //  Value is zero 

               AppDomain.Unload(ad)
    }
    {       
                AppDomain ad = AppDomain.CreateDomain("NewDomain");
                Managed c = ad.CreateInstanceAndUnwrap(a.FullName, typeof(Managed).FullName) as Managed;
                int val2 = c.CallLibFunc();
                //  I think value is one

               AppDomain.Unload(ad)
    }
Managed c1 = new Managed(); 


}

如果你不想要取决于这种线,您可以创建一个包装ManagedIsolated.dll 将参考managed.dll 并将使每一个呼叫中单独域具有域卸载之后的呼吁。主要应用程序将仅仅取决于ManagedIsolated.dll 类型和Managed.dll 不会被载入主要的应用领域。

这看起来像一个伎俩,但可能是它将是有用的人。`

在短期,也许。应用程序域是一个纯粹的管理概念。当一个程序域的实例,它没有地图在新的副本的基础Dll,它可以重复使用的代码已经在存储器(例如,你不会希望它加载新的副本所有的系统。 集会,对吗?)

在管理世界所有静态的变量范围的通过程序域,但正如你指出这并不适用于不受管理的世界。

你可以做一些事情复杂,部队负荷的一个独特的managed.dll 每个应用领域,这将导致一个新版本的静态lib被带。例如,也许使用的组件。载有一个字节列会的工作,但我不知道如何CLR会试图处理的冲突的类型,如果同组件装载的两倍。

我不认为我们得到的实际问题在这里 看看这DDJ的文章.

默认值的加载程序优化属性是SingleDomain,其中"导致域载入一个私人复制的每个必要组件的代码"。即使它是一个多领域值"每域始终保持一个独特的静态复制领域"。

'managed.dll'为(正如其名称所暗示的)是管理大会。代码在静态的。lib已静态汇编(以IL代码)成'managed.dll',所以我希望同样的行为如Lenik的期望。...

...除非静态的。lib是一个静态的出口库不受控DLL。Lenik说不是这种情况,所以我还不确定怎么在这里。

你有没有尝试运行独立的进程?一个静态的图书馆应该不共享内存的实例之外,它自己的过程。

这可能是一个痛苦的管理,我知道。我不知道你其他的选择将是在这种情况下,虽然。

编辑:后一点看周围我想你可以做一切你需要的 系统。诊断。过程 类。你会有很多的选择在这一点通信的但是 .网远程处理 或WCF可能会很好和容易的选择。

这些都是最好的两篇文章我发现的主题

重要的部分是:

空中航线管理局的基于静态领域是处理-全球性的。这些限制为标量和价值的类型,因为我们不想允许对象的流血跨域的界限。这将导致各种各样的问题,特别是在程序域卸载。一些语言,如ILASM和MC++使其方便的定义空中航线管理局的基于静态的领域。大多数语言不这样做。

好,如果你要控制的代码。lib,我想试试

class CallCountHolder {
   public:
     CallCountHolder(int i) : count(i) {}
     int count;
};

static CallCountHolder cc(0);
int TheFunction()
{
    printf("Function called");
    return cc.count++;
}

因为他说,空中航线管理局的基于静态领域是有限的标量和价值的类型。Int阵列可能还会的工作。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top