从 main.c 中进行单个定义,以便在编译时可用于库

发布于 2024-12-02 22:43:49 字数 1067 浏览 2 评论 0原文

假设我有一个 ma​​in.c 文件

#include "library.h"
#define LIBRARY_VALUE 5

int main(void)
{
    somefunction1();
    return 0;
}

library.h

void somefunction1(void);

library.c

#include "library.h"
#ifndef LIBRARY_VALUE
#define LIBRARY_VALUE 1
#endif

static unsigned char oneString[LIBRARY_VALUE]; // Also I need to be able
                                               // to use the value to initialize
                                               // static arrays that will be
                                               // modified by somefunction1();
void somefunction1(void)
{
    printf("The Library Value is %d\n", LIBRARY_VALUE);
}

我想要在这里做的是能够编译 main .c 并按照我在 ma​​in.c 中的 include 之后定义的方式使用 LIBRARY_VALUE 的值。
我应该如何使用GCC来实现这一目标? 我确实需要ma​​in.c中定义该值。

如果我必须更改代码,请提供最低限度的工作示例代码。所以我清楚地知道该怎么做。谢谢。

Lets say I have a main.c file

#include "library.h"
#define LIBRARY_VALUE 5

int main(void)
{
    somefunction1();
    return 0;
}

library.h

void somefunction1(void);

library.c

#include "library.h"
#ifndef LIBRARY_VALUE
#define LIBRARY_VALUE 1
#endif

static unsigned char oneString[LIBRARY_VALUE]; // Also I need to be able
                                               // to use the value to initialize
                                               // static arrays that will be
                                               // modified by somefunction1();
void somefunction1(void)
{
    printf("The Library Value is %d\n", LIBRARY_VALUE);
}

What I want to do here, is to be able to compile main.c and having LIBRARY_VALUE‘s value to be used as I defined right after the include in main.c.
How should I use GCC in order to achieve this?
I do need the value to be defined in main.c.

In case I have to change my code, I need a minimum working example code please. So I know clearly how to do this. Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

も让我眼熟你 2024-12-09 22:43:49

在 C 中,不同的 .c 文件无法共享其中一个 .c 文件中定义的公共宏。传统做法是把它放在 .h 文件中,但你说这对你不起作用。

您将需要一种“构造函数”函数来在运行时设置“静态”信息。该构造函数可以由 main.c 直接调用,也可以通过让 main.c 定义库选取的 extern 来间接调用。

我会给你一些代码,但我还没有尝试编译它......我将把它作为学生的练习。

main.c

#include "library.h"
int const library_value = 5;

int 主函数(无效) { 某个函数1(); 返回0; }

library.h

extern int const library_value;
void somefunction1(void);

library.c

#include <assert.h>
#include "library.h"

static unsigned char *oneString;

// destroy any memory from lib_init().
static void lib_clear(void)
{
    if ( oneString )
    {
        free(oneString);
        oneString = NULL;
    }
}

// initialization - strop the static if the caller is to start it up.
static void lib_init( void )
{
    if ( ! oneString )             // (defensive "if" to be sure)
    {  
        assert( library_value > 0 );

        oneString = (unsigned char*)malloc( library_value );

        atexit( &lib_clear );
    }    
}


void somefunction1(void)
{
    if ( ! oneString )    // if the main() is not calling an the constructor then
        lib_init();       //  // every method within the library must do so.

    printf("The Library Value is %d\n", library_value);
}

lib_init() 和 lib_clear() 方法可以通过 lib_init( int size ) 签名来外部化以获取大小。

In C there is no way for different .c files to share a common macro defined in one of the .c files. The tradition is to put it in a .h file, but you say this will not work for you.

You will need a type of "constructor" function that sets up your "static" information at run time. This constructor can be called directly by main.c, or indirectly by having main.c define an extern the library picks up.

I'll throw you some code, but I haven't tried to compile it... I'll leave that as an exercise for the student.

main.c

#include "library.h"
int const library_value = 5;

int main(void) { somefunction1(); return 0; }

library.h

extern int const library_value;
void somefunction1(void);

library.c

#include <assert.h>
#include "library.h"

static unsigned char *oneString;

// destroy any memory from lib_init().
static void lib_clear(void)
{
    if ( oneString )
    {
        free(oneString);
        oneString = NULL;
    }
}

// initialization - strop the static if the caller is to start it up.
static void lib_init( void )
{
    if ( ! oneString )             // (defensive "if" to be sure)
    {  
        assert( library_value > 0 );

        oneString = (unsigned char*)malloc( library_value );

        atexit( &lib_clear );
    }    
}


void somefunction1(void)
{
    if ( ! oneString )    // if the main() is not calling an the constructor then
        lib_init();       //  // every method within the library must do so.

    printf("The Library Value is %d\n", library_value);
}

The lib_init() and lib_clear() methods could be made externs with a lib_init( int size ) signature to take the size.

最丧也最甜 2024-12-09 22:43:49

您的目标似乎有一个引用多个位置的定义。

可能性有限:

  1. #define in .h
  2. extern 在 main 或库之外的其他地方定义。
  3. extern 在库中定义。
  4. 调用者传递给库的值,可能是库的初始化调用。
  5. 在#include library.h 之前定义的内容由library.h 选取。我不喜欢这个。
  6. 正如 alfa 所说,使其成为编译时定义。

Library.h 中#define 的示例。

// library.h
#ifndef LIBRARY_VALUE
#define LIBRARY_VALUE 1

void somefunction1(void);

#endif

或者,让 main 定义一个由调用者定义并由库引用的值:

// library.h
extern int const library_value;   // caller to define in main
void somefunction1(void);         // function for caller
// main.c
int const library_value  = 5;

int main(void)
{
    somefunction1();
    return 0;
}

我不喜欢的是:

//main.c
#define LIBRARY_VALUE 5
#include "library.h"
//library.h
#ifdef LIBRARY_VALUE
int const library_value = LIBRARY_VALUE;  // executable code in .h files is evil
#endif

我不喜欢这个的一些原因是,如果两个或多个库的调用者,它是模糊且非常规的.h 定义 LIBRARY_VALUE 您将,或者至少应该,得到模糊的链接时间错误。如果 LIBRARY_VALUE 未由 #include 定义,则同样适用。library.c 本身无法定义默认值。不,我宁愿为接受常量的库调用初始化函数。

Your goal seems to have a single definition referenced multiple places.

There are a limited number of possibilities:

  1. #define in .h
  2. extern defined in main, or somewhere else outside of library.
  3. extern defined in library.
  4. Value passed by caller to library, perhaps an initialization call for the library.
  5. Something defined before #include library.h that is picked up by library.h. I don't like this one.
  6. As alfa says, make it a compile-time definition.

An example of a #define within library.h.

// library.h
#ifndef LIBRARY_VALUE
#define LIBRARY_VALUE 1

void somefunction1(void);

#endif

Or, have main define a value defined by the caller and referenced by the library:

// library.h
extern int const library_value;   // caller to define in main
void somefunction1(void);         // function for caller
// main.c
int const library_value  = 5;

int main(void)
{
    somefunction1();
    return 0;
}

The one I don't like is:

//main.c
#define LIBRARY_VALUE 5
#include "library.h"
//library.h
#ifdef LIBRARY_VALUE
int const library_value = LIBRARY_VALUE;  // executable code in .h files is evil
#endif

Some of the reasons I dont' like this is that it is obscure and unconventional, if two or more callers of library.h define LIBRARY_VALUE you will, or at least should, get obscure link time errors. The same applies if LIBRARY_VALUE is not defined by an #include... library.c itself can not define a default value. No, I'd much rather call an initialization function for the library that accepts the constant.

北城孤痞 2024-12-09 22:43:49

您似乎希望这种工作方式的问题在于,编译库时会使用常量 - 您不能在编译库时使用一个值,然后使用不同的值编译一个程序并期望库的代码神奇地改变以使用新常量。不过,当谈到替代方案时,您有一些选择。

您可以将数组移动到程序中而不是库中,并为库提供指向它的指针及其大小。

或者您可以使用库中动态分配的数组,并添加初始化函数来进行分配(使用程序提供的大小)。

或者,您可以放弃该库,只将其代码编译为程序的一部分 - 然后您可以使用为程序定义的常量,只要它在(以前的)库代码将看到它的地方完成即可。

The problem with the way you seem to want this to work, is that the constant gets used when the library is compiled -- you can't use one value when compiling the library and then compile a program with a different value and expect the library's code to magically change to use the new constant. You have some options when it comes to alternatives, though.

You could move the array into the program rather than the library, and give the library a pointer to it, and its size.

Or you could use a dynamically allocated array in the library, and add an initialization function to do the allocation (using the size provided by the program).

Or, you could ditch the library and just compile its code as part of the program -- then you can use a constant defined for the program as long as its done where the (previously) library code will see it.

别挽留 2024-12-09 22:43:49

建议(假设您希望“myarray”在库外部可见):

// library.h
#ifndef LIBRARY_H
#define LIBRARY_Y

#define ARRAY_SIZE 5

extern unsigned char myarray[ARRAY_SIZE]; // Also I need to be able
                                          // to use the value to initialize
                                          // static arrays that will be
                                          // modified by somefunction1();
void somefunction1(void);         // function for caller

#endif
/* LIBRARY_H */

否则,如果您只想要“somefunction1()”和数组大小,则声明另一个函数“array_size ()”:

// library.h
#ifndef LIBRARY_H
#define LIBRARY_Y

#define ARRAY_SIZE 5

int array_size ();                // library.c will define "myarray" and it will
                                  // define function array_size as "return ARRAY_SIZE;"
void somefunction1(void);         // function for caller

#endif
/* LIBRARY_H */

另外:
请记住,“静态”有两个含义:

1) 隐藏变量或函数名称对文件范围的可见性(该名称在源文件之外“不可见”)

2) 从静态存储中为对象分配空间(而不是静态存储)堆(malloc/new)或堆栈(局部变量))。

如果你只想要“静态存储”部分;那么你不需要关键字“static”。只需在函数外部定义变量即可:)。

另一个问题是您是否想让“ARRAY_SIZE”成为编译时变量。如果是这样,您应该确保它只定义一次(当编译library.c时),并且仅在一个地方使用(仅library.c和library.c)。例如:

// library.c
#include "library.h"

#ifndef ARRAY_SIZE
  #error ARRAY_SIZE IS UNDEFINED!
#else
static unsigned char myarray[ARRAY_SIZE]; 

int array_size ()
{
  return ARRAY_SIZE;
}
#endif
...

Recommendation (assuming you want "myarray" visible outside the library):

// library.h
#ifndef LIBRARY_H
#define LIBRARY_Y

#define ARRAY_SIZE 5

extern unsigned char myarray[ARRAY_SIZE]; // Also I need to be able
                                          // to use the value to initialize
                                          // static arrays that will be
                                          // modified by somefunction1();
void somefunction1(void);         // function for caller

#endif
/* LIBRARY_H */

Otherwise, if you just want "somefunction1()" and the array size, then declare another function, "array_size ()":

// library.h
#ifndef LIBRARY_H
#define LIBRARY_Y

#define ARRAY_SIZE 5

int array_size ();                // library.c will define "myarray" and it will
                                  // define function array_size as "return ARRAY_SIZE;"
void somefunction1(void);         // function for caller

#endif
/* LIBRARY_H */

ALSO:
Please remember that "static" has two meanings:

1) Hides visibility of a variable or function name to file scope (the name is "invisible" outside of the source file)

2) allocates space for the object from static storage (instead of the heap (malloc/new) or stack (local variables)).

If you only want the "static storage" part; then you don't need the keyword "static". Just define your variable outside of a function, and you're set :).

Yet another issue is whether you want to make "ARRAY_SIZE" a compile time variable. If so, you should make sure it gets defined EXACTLY ONCE (when library.c is compiled), and is used IN ONLY ONE PLACE (library.c and library.c only). For example:

// library.c
#include "library.h"

#ifndef ARRAY_SIZE
  #error ARRAY_SIZE IS UNDEFINED!
#else
static unsigned char myarray[ARRAY_SIZE]; 

int array_size ()
{
  return ARRAY_SIZE;
}
#endif
...
哎呦我呸! 2024-12-09 22:43:49

您尝试做的事情是不可能的,因为library.c 和main.c 是单独编译的。您应该使用“gcc -DLIBRARY_VALUE=5 ...”来编译library.c。

What you are trying to do is not possible because library.c and main.c are compiled separately. You should compile library.c with "gcc -DLIBRARY_VALUE=5 ..." instead.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文