问题(简化以使事情更清楚):
-
1. 有一个静态链接的 static.lib 具有递增的功能:
extern int CallCount = 0;
int TheFunction()
{
void *p = &CallCount;
printf("Function called");
return CallCount++;
}
2. static.lib 链接到一个托管的 C++/CLI managed.dll,它包装了 TheFunction 方法:
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
}
问题:
根据我在 Don Box 的 Essential .NET Vol1 The CLR 中阅读的内容,我希望 val2 为零,因为在调用 CreateInstanceAndUnwrap 时加载了 managed.dll/static.lib 的全新拷贝。我误解了发生了什么吗?静态库似乎不遵守应用程序域边界,因为它是非托管代码。除了创建用于实例化托管的全新流程之外,是否有其他方法可以解决此问题?
非常感谢大家!
最佳答案
我的直觉是,正如您所怀疑的那样,非托管 DLL 在进程的上下文中加载,而不是在 AppDomain 的上下文中加载,因此非托管代码中的任何静态数据都在 AppDomain 之间共享。
This link显示与您有相同问题的人,仍未对此进行 100% 验证,但可能是这种情况。
This link是关于使用 thunking 技巧创建从非托管代码到 AppDomain 的回调。我不确定这对您有帮助,但也许您会发现这对创建某种解决方法很有用。
关于c# - 具有托管代码问题的静态库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72769/