0

我有这些 2 c 文件和一个头文件。所有这些文件都是由Makefile.

mysql_storage.h

#include <stdio.h>
#include <mysql.h>
#include <glib/gstdio.h>

#if 1
typedef enum {
        STORAGE_OK = 0,
        STORAGE_NO_SUCH_USER,
        STORAGE_INVALID_PASSWORD,
        STORAGE_ALREADY_EXISTS,
        STORAGE_OTHER_ERROR/* Error that isn't caused by user input, such as 
                               a database that is unreachable. log() will be 
                               used for the exact error message */
} storage_status_t;

typedef enum
{
    MYSQL_PASS_CHECK_ONLY = -1,
    MYSQL_PASS_UNKNOWN = 0,
    MYSQL_PASS_WRONG,
    MYSQL_PASS_OK
} mysql_pass_st;
#endif

static void mysql_storage_init( void );
static void mysql_storage_deinit( void );
static storage_status_t mysql_storage_load(const char *password );
static storage_status_t mysql_storage_check_pass( const char *nick, const char *password );
static storage_status_t mysql_storage_save( int overwrite );
static storage_status_t mysql_storage_remove( const char *nick, const char *password );

mysql_storage.c

#include "mysql_storage.h"

MYSQL *mysql;

static void mysql_storage_init( void ) {
    if (mysql_init(mysql) == NULL)
        fprintf( stderr, "Can not initialize MySQL. Configuration won't be saved.");

    if (!mysql_real_connect(mysql, "localhost", "USERNAME", "PASSWORD", NULL, 3306, NULL, 0))
        fprintf( stderr, "%s\nConfiguration won't be saved.", mysql_error(mysql));

    if (mysql_select_db(mysql, "DATABASENAME"))
        fprintf( stderr, "%s\nConfiguration won't be saved.", mysql_error(mysql));
}
static void mysql_storage_deinit( void ) {
    if(mysql!=NULL) 
        mysql_close(mysql);
}
static storage_status_t mysql_storage_check_pass( const char *nick, const char *password ){    return STORAGE_OTHER_ERROR;}
static storage_status_t mysql_storage_load(const char *password ){    return STORAGE_OTHER_ERROR;}
static storage_status_t mysql_storage_save( int overwrite ){    return STORAGE_OTHER_ERROR;}
static storage_status_t mysql_storage_remove( const char *nick, const char *password ){    return STORAGE_OTHER_ERROR;}

主程序

#include<stdio.h>
#include "mysql_storage.h"

    int main(){
        // connect mysql
        mysql_storage_init();
        // check a password
        printf("check password: %d\n:", mysql_storage_check_pass("hello", "world"));
        // close mysql
        mysql_storage_deinit();
    }

最后是Makefile

CFLAGS=-I/usr/include/mysql -DBIG_JOINS=1 -fno-strict-aliasing -g -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I.
LIBS=-L/usr/lib/x86_64-linux-gnu -lmysqlclient -lpthread -lz -lm -lrt -ldl -lglib-2.0 -L.
CC=gcc

all: main
clean:
        rm main  *.o
main: mysql_storage.o main.o 
        $(CC)  main.o mysql_storage.o $(LIBS) -o main
.c.o:
        $(CC) -c $(CFLAGS) $<

当我做时,我得到这个错误。

gcc  main.o mysql_storage.o -L/usr/lib/x86_64-linux-gnu -lmysqlclient -lpthread -lz -lm -lrt -ldl -lglib-2.0 -L. -o main
main.o: In function `main':
/home/shiplu/projects/mysql_interface/main.c:8: undefined reference to `mysql_storage_init'
/home/shiplu/projects/mysql_interface/main.c:11: undefined reference to `mysql_storage_check_pass'
/home/shiplu/projects/mysql_interface/main.c:15: undefined reference to `mysql_storage_deinit'
collect2: ld returned 1 exit status

如您所见,我正在链接main.omysql_storage.o. 所以它不应该抛出未定义的引用错误。这里有什么问题?

4

5 回答 5

4

You declared your functions mysql_storage_init as static, meaning they have internal linkage -- this means they are not visible to other translation units.

Since you need to call them from other object files, you should instead declare them to have external linkage by omitting the static keyword in their declarations and definitions. The prototypes in the header file may optionally declare them extern, but that is not required, since the linkage is external by default.

于 2012-07-13T19:02:48.327 回答
3

You mysql_storage.c functions are defined as static, which means they are not visible outside of the file. Remove static and it should work.

于 2012-07-13T19:01:51.157 回答
3

The static keyword for a function means this function will have the scope of this .obj file only, which is probably not what you expect. Remove the static keyword for function definitions and declarations (both .h and .cpp files)

于 2012-07-13T19:02:31.943 回答
1

在函数之前使用关键字 static 可确保它们仅在定义它们的编译单元中可见。如果您从函数中删除 static 关键字,您应该没有问题。

于 2012-07-13T19:03:32.513 回答
0

如果您计划在不同的编译单元中使用函数,则不应将它们声明为静态的。

于 2012-07-13T19:03:47.817 回答