Reputation: 321
I am making a resource system that similar to Qt's qrc.
The resource is automatically created to .c file contains byte array. And it compiled to static library.
And it has a header file looks like below. I don't know which hash value comes so I defined a macro function.
#ifndef BRC_6c26e83425a54300d410b49c1aa1c3ea
#define BRC_6c26e83425a54300d410b49c1aa1c3ea
void bl_register_resource_6c26e83425a54300d410b49c1aa1c3ea();
#ifdef BL_REGISTER_RESOURCE
#undef BL_REGISTER_RESOURCE
#endif
#define BL_REGISTER_RESOURCE() \
bl_register_resource_6c26e83425a54300d410b49c1aa1c3ea();
#endif
It is intended to use as
void init_function()
{
#include "path/to/resource/resource.h"
BL_REGISTER_RESOURCE()
// Resource is registered in global singleton object
// and now I can access the resource from it.
#include "path/to/resource/another.h"
BL_REGISTER_RESOURCE()
// Another resource register function is called.
}
It worked find when I use C. But the code base has moved to C++, now I can't use this trick because include and call macro function may happened in C++ namespace.
namespace my {
MyClass::MyClass()
{
#include "path/to/resource/resource.h"
BL_REGISTER_RESOURCE()
}
} // namespace my
I found that I can't use extern "C" in function definition. The function declaration void bl_register_resource_HASH();
will be my::bl_register_resource_HASH();
but the function definition has no namespace. This causes "undefined reference to my::bl_register_resource_HASH()".
Include the header outside of namespace works fine. But in this time I can't use multiple macro call trick.
I tried void ::bl_register_resource_HASH();
but it doesn't worked.
Is there any way to declare global scope function in namespace?
Upvotes: 0
Views: 111
Reputation: 38518
I see the only simple way is
#ifndef BRC_6c26e83425a54300d410b49c1aa1c3ea
#define BRC_6c26e83425a54300d410b49c1aa1c3ea
void bl_register_resource_6c26e83425a54300d410b49c1aa1c3ea();
#endif
#ifdef BL_REGISTER_RESOURCE
#undef BL_REGISTER_RESOURCE
#endif
#define BL_REGISTER_RESOURCE() \
::bl_register_resource_6c26e83425a54300d410b49c1aa1c3ea();
And usage
#include "path/to/resource/resource.h"
#include "path/to/resource/other.h"
namespace my {
MyClass::MyClass()
{
#include "path/to/resource/resource.h"
BL_REGISTER_RESOURCE()
#include "path/to/resource/other.h"
BL_REGISTER_RESOURCE()
}
}
I have moved #endif
to make repeated #include
being able to define the macro BL_REGISTER_RESOURCE()
Function like macros require special settings in clang-format. It is better
#define BL_REGISTER_RESOURCE() \
::bl_register_resource_6c26e83425a54300d410b49c1aa1c3ea()
BL_REGISTER_RESOURCE();
Upvotes: 1