Right way to initialize a static library (C++)?

Viewed 85

I have a static C library that I want to port to C++, in the C library I got some global variables that store some common data used by the functions for example:

// global variable in the C library
int global_number_of_cpu_cores;

init_global_vars()
{
    global_number_of_cpu_cores = get_info();
}
    
void lib_function()
{
    // use global_number_of_cpu_cores
}

when using the library, it must be first initialized by the init function but in C++, the object's constructors are executed before the main function, so I cannot code:

class class_lib
{
    class_lib()
    {
         // use global_number_of_cpu_cores but this is uninitialized!
    }
}

Also, you can initialize global variables with functions:

int program_var = lib_function(); // lib_function uses global_number_of_cpu_cores but this is unintialized!

what is a decent/elegant way to solve this when designing a C++ library? how do well-designed C++ libraries like Boost, Qt, etc solve this? any idea?

1 Answers

What you can do - simply create a C wrapper interface for C++ I.e. something like following:

In header file, e.g. foo.h

#ifndef __FOO_H_INCLUDED__
#define __FOO_H_INCLUDED__

#ifdef __cplusplus
extern "C" {
#endif

void print_logical_cpus()

#ifdef __cplusplus
}
#endif / * extern "C"  */

#endif / * __FOO_H_INCLUDED__  */

in the implementation file e.g. foo.cpp

#include "foo.h"
#include <cstdio>
#include <thread>

struct GlobalSettings {
 GlobalSettings():
   logical_cpus(std::thread::hardware_concurrency())
 {}
  std::size_t logical_cpus;
};

static GlobalSettings __gsettings;

extern "C" {

  void print_logical_cpus()
  {
      std::printf("Logical cpus %z", __gsettings.logical_cpus);
  }

}

If you still need to port on raw C, there are compiler specific tricks to run functions before and after main. GCC uses attribute((constructor)) and attribute((destructor))) MS VC++ uses __declspec(allocate(".CRT$XLC"))

Related