Автоматическая процедура инициализации в библиотеке C ++? - PullRequest
0 голосов
/ 01 мая 2010

Если у меня есть заголовочный файл foo.h и исходный файл foo.cpp, а foo.cpp содержит что-то вроде:

#ifdef WIN32
class asdf {
   asdf() { startup_code(); }
   ~asdf() { cleanup_code(); }
};
asdf __STARTUP_HANDLE__
#else
//unix does not require startup or cleanup code in this case
#endif

но foo.h не определяет класс asdf, скажем, у меня есть приложение bar.cpp:

#include "foo.h"
//link in foo.lib, foo.dll, foo.so, etc
int main() {
   //do stuff
   return 0;
}

Если bar.cpp скомпилирован на платформе WIN32, будут ли вызываться asdf () и ~ asdf () в соответствующее время (перед main () и при выходе из программы, соответственно), даже если класс asdf не определен в foo.h, но связан через foo.cpp?

Ответы [ 4 ]

5 голосов
/ 01 мая 2010

Да, но будьте очень осторожны. Порядок инициализации статических объектов (например, вашего asdf объекта) не определен. Таким образом, поведение неопределенное, если какой-либо другой объект пытается сослаться на ваш объект до main().

Кроме того, __STARTUP_HANDLE__ не является допустимым идентификатором. Двойное подчеркивание не допускается ни в одном идентификаторе (даже в макросах), а также одно подчеркивание, за которым следует заглавная буква.

1 голос
/ 01 мая 2010

Если это не сломано, не исправляйте это. Обратите внимание на проблему статического порядка инициализации, как говорят другие ответы. Но вы действительно должны исправить этот зарезервированный идентификатор.

__STARTUP_HANDLE__ работает аналогично библиотеке времени выполнения, и библиотеки времени выполнения используют подобные имена, но это не часть библиотеки времени выполнения, поэтому это имя не разрешено.

#ifdef WIN32
namespace { // anonymous namespace - no outside access
class asdf {
   asdf() { startup_code(); }
   ~asdf() { cleanup_code(); }
} x; // to create an instance
}
0 голосов
/ 01 мая 2010

В Windows и с DLL у вас есть возможность использовать функцию DllMain, которая будет вызываться при загрузке и т. Д.

BOOL WINAPI DllMain(HINSTANCE hinstDLL,
                    DWORD fdwReason,
                    LPVOID lpvReserved) {  

  switch (fdwReason) {

  case DLL_PROCESS_ATTACH:    
    break;

  case DLL_THREAD_ATTACH:
    break;

  case DLL_THREAD_DETACH:
    break;

  case DLL_PROCESS_DETACH:
    break;

  default:
    break;
  }

  return TRUE;
}
0 голосов
/ 01 мая 2010

Пока сами объекты (foo.o) связаны в исполняемый файл, это будет работать (при условии, что фиаско порядка статической инициализации вас не поразит). Однако, если вы извлекаете его из библиотеки (foo.lib), этого не произойдет, если вы явно не отметите объект как «активный объект», но я не помню, как это сделать в MSVC.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...