使用未定义的宏构建库

时间:2015-04-24 16:12:16

标签: c++

如果我有两个项目和一个库。该库需要一个定义的宏,所以

/* mylib.cpp */
int stack[STACK_SIZE];

在项目1中,堆栈大小需要定义为:

/* project_1_main.cpp */
#define STACK_SIZE 50

对于Project 2,堆栈大小需要不同

/* project_2_main.cpp */
#define STACK_SIZE 800

有没有办法构建一个带有未定义宏的库,并让它留给项目定义?

我正在使用GCC编译器,C ++ 03,但我不允许将库转换为模板。

编辑:根据您的输入,我决定不预先编译库,使用目录作为包含的源文件,然后添加-D STACK_SIZE = 50选项,以相应的大小编译每个项目。更长的清洁构建,但它是干的。

2 个答案:

答案 0 :(得分:3)

不,这是不可能的。在编译库时,必须在中定义作为库一部分的源文件中使用的宏;稍后在另一个源文件中重新定义宏将不会改变库的行为。

如果您需要对库的行为进行修改,您很可能需要根据传递给库中函数的值动态分配此数组,例如

int *stack = NULL;
size_t stack_size = 0;

void mylib_init_stack(size_t size) {
    if (stack == NULL) {
        stack = malloc(size * sizeof(int));
        stack_size = size;
    } else {
        fprintf(stderr, "mylib ERROR: stack already initialized\n");
    }
}

并在启动应用程序时调用该函数来初始化库。

答案 1 :(得分:2)

  

“有没有办法构建一个带有未定义宏的库,并让它留给项目定义?”

您可以使用模板参数,以及依赖项目中使用的小包装类而不是该宏:

stack.hpp

 template<size_t StackSize>
 struct stack_impl {
     static std::array<int,StackSize> stack;
 };

 template <size_t StackSize>
 std::array<int,StackSize> stack_impl<StackSize>::stack;

依赖项目使用它像

project_1_main.cpp

 #include "stack.hpp"
 typedef stack_impl<50> Project1Stack;

project_2_main.cpp

 #include "stack.hpp"
 typedef stack_impl<800> Project2Stack;

访问

 Project1Stack::stack[5] = 6;


 std::cout << Project2Stack::stack[42] << std::endl;

无论如何,您可能希望使用为传递的int数组指定的特定大小运行的通用函数实现(独立于实际项目设置)。因此,您可以为使用指针和大小操作的API创建简单的包装器:

 class stack_base {
     int* stack_start_;
     const size_t size_;
 protected:
     stack_base(int* stack_start, const size_t size)
     : stack_start_(stack_start), size_(size) {}
 public: 
     // Provide public interface to operate on stack
     void push(int);
     int pop();
 };

 template<size_t Size>
 class stack : public stack_base {
     std::array<int,Size> stack_mem;

 public:
     stack() 
     : stack_base(&stack_mem[0],stack_mem.size()) {
     }
 };