两个静态成员的实例,怎么可能? [英] two instances of a static member, how could that be?

查看:146
本文介绍了两个静态成员的实例,怎么可能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个多线程应用程序。
我在共享库中声明一个具有静态成员的类。



从不同库中的不同线程打印成员的地址显示不同的结果。 p>

//声明

  template< class OBJECT& 
struct Container
{
static int m_member;
};

template< class OBJECT>
int Container< OBJECT> :: m_member;

//打印



< cout< (void *)& Container< int> :: m_member<< endl;

这是怎么回事?

解决方案

如果你有不同的库,(我猜猜不同的动态库),那么你可能有一些重复的代码和静态变量。



确切的细节将取决于您使用的特定动态库技术。我想说,例如,在Windows DLL中,你将有重复的代码和变量,但在Linux SO中你不会。



无论如何,你应该给更多的细节。



UPDATE :但是你的类是一个模板!在共享库中的模板实例化是一个奇怪的野兽!为了确保在所有进程中只使用类的一个副本,必须显式实例化模板,并确保此实例化导出到SO中,并且它从客户端代码使用。细节因编译器而异,但您可以检查 std :: string 是如何完成的,例如:



在头文件中:

 命名空间std 
{
extern template class basic_string< wchar_t>
}

在库的源代码:

 命名空间std 
{
模板类basic_string< wchar_t> ;;
}



当然,您需要事先知道您的模板需要哪些实例化。显然,SO不能导出使用其不知道的类型的实例化。



UPDATE :但是你有两个不同的库模板...然后如果两个库定义显式实例化为 extern ,共享ELF魔法应该将两个实例化合并为一个。



YET ANOTHER UPDATE :在使用模板和共享对象之后,通常只是工作。我现在的猜想是,你正在使用 -fvisibility = hidden 或类似的来编译库。如果是这样的话,只要写:

  template< class OBJECT> 
struct __attribute __((visibility(default)))容器
{
static int m_member;
};

使模板的特殊化进入动态符号表,从而避免重复。 / p>

I have a multithreaded application. I declare a class with a static member in a shared library.

Printing the address of the member from different threads from different libraries shows different results.

//declaration

template <class OBJECT>
struct Container
{
   static int m_member;
};

template <class OBJECT>
int Container<OBJECT>::m_member;

// printing

cout << (void*) &Container<int>::m_member << endl;

How could that be?

解决方案

If you have different libraries, (I'm guessing different dynamic libraries), then you may have some duplication of both code and static variables.

The exact details will depend on the particular dynamic library technology you are using. I'd say that, for example, in Windows DLLs you will have duplicated code and variables, but in Linux SOs you will not.

Anyway, you should give more details on the Operating System and the layout of your project.

UPDATE: Ahh, but your class is a template! Template instantiations in a shared library are a strange beast! To make sure that only one copy of your class is used across all the process you have to explicitly instantiate the template and make sure that this instantiation is exported in the SO, and that it is used from the client code. The details vary with the compiler, but you can check how the std::string is done, for example:

In the header file:

namespace std
{
    extern template class basic_string<wchar_t>;
}

In the source of the library:

namespace std
{
    template class basic_string<wchar_t>;
}

Naturally you need to know in advance which instantiations will be needed of your template. Obviously, the SO cannot export an instantiation that uses a type it knows nothing about.

UPDATE: Ahh, but you have two different libraries instantating the template... then if both libraries define the explicit instantiation as extern the shared ELF magic should merge both instantiations into one.

YET ANOTHER UPDATE: After playing with templates and shared objects, it usually just works. My guess now is that you are compiling the libraries with -fvisibility=hidden or similar. If that is the case, it would be enough just to write:

template <class OBJECT>
struct __attribute__((visibility("default"))) Container
{
   static int m_member;
};

To make the specializations of the template to enter the dynamic symbol table, and thus avoid the duplication.

这篇关于两个静态成员的实例,怎么可能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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