MWin123 MWin123 - 1 month ago 7
C Question

C - Proper reuse of code / methods between files

I'm a C beginner with average Java Skills and I'm not sure how to reuse C code between files properly.

Let's say I have two files / modules:

server.c
and
client.c


They are not linked (with GCC) and should run in separate processes.

There are two methods in
server.c
that I want to use in
client.c
. Those methods use global, static (const) variables in the same module. Basically I want the same functionally as when I would copy them into the other file.

Small example:

server.c


static const char *progname = "server";

static int sockfd = -1;
static int connfd = -1;

static void free_resources(void)
{
if (sockfd >= 0) {
(void) close(sockfd);
}

if (connfd >= 0) {
(void) close(connfd);
}
}


client.c


static const char *progname = "client";

static int sockfd = -1;
static int connfd = -1;

// I want to use free_resources here


If I want to use the same method in
client.c
, what would be the right way to do it?

If I create a separate
util.c
/
util.h
module with the method, how do I access the global variables? Should I pass them as arguments every time? Remove static?

In Java I would probably create a class and pass the (reference to the) global variables once. Is there a similar approach in C?

Answer

In Java I would probably create a class...

The equivalent in C is to create a structure, and pass a pointer to the structure to any functions that need access to the variables. The structure declaration should be in utils.h, e.g.

typedef struct
{
    char *progname;
    int sockfd;
    int connfd;
}
Info;

void free_resources( Info *info );

Create and initialize the structure in server.c and client.c, and then pass the address to the common functions, e.g.

Info server_info = { "server", -1, -1 };

int main( void )
{
    // ...

    free_resources( &server_info );
}

Then the code in utils.c looks like this. (Note that you can't use the static keyword, since the function must be callable from outside utils.c)

void free_resources( Info *info )
{
    if (info->sockfd >= 0) {
        (void) close(info->sockfd);
    }

    if (info->connfd >= 0) {
        (void) close(info->connfd);
    }
}