问题(简化以使事情更清楚):
1.有一个静态链接的static.lib,它有一个递增的函数:
extern int CallCount = 0;
int TheFunction()
{
void *p = &CallCount;
printf("Function called");
return CallCount++;
}
2. static.lib链接到托管TheFunction方法的托管C/C++LI managed.dll:
int Managed::CallLibFunc()
{
return TheFunction();
}
3.测试应用程序有一个对managed.dll的引用,并创建多个调用C/C++LI包装器的域:
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
}
题:
根据我在Don Box的Essential .NET Vol1 The CLR中所读到的内容,我希望val2为零,因为在调用CreateInstanceAndUnwrap时会加载一个全新的managed.dll / static.lib副本.我误解了发生了什么事吗?静态库似乎不尊重appdomain边界,因为它是非托管代码.有没有办法绕过这个问题,而不是创建一个全新的过程来实例化托管?
非常感谢大家!
解决方法:
我的预感是,正如您所怀疑的那样,非托管DLL在进程的上下文中而不是在AppDomain的上下文中加载,因此非托管代码中的任何静态数据都在AppDomains之间共享.
This link显示您遇到同样问题的人,仍然没有100%验证这一点,但可能就是这种情况.
This link是关于使用thunking技巧创建从非托管代码到AppDomain的回调.我不确定这可以帮到你,但也许你会发现这对创建某种解决方法很有用.