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;}

main.c

#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.oしてmysql_storage.oいます。したがって、未定義の参照エラーをスローしないようにする必要があります。ここでの問題は何ですか?

4

5 に答える 5

4

mysql_storage_init関数をとして宣言しました。これは、関数が内部リンクstaticを持っていることを意味します。これは、他の変換ユニットからは見えないことを意味します。

他のオブジェクトファイルから呼び出す必要があるため、代わりに、宣言と定義でキーワードを省略して、外部リンクがあることを宣言する必要があります。staticヘッダーファイルのプロトタイプはオプションでそれらexternを宣言できますが、リンケージはデフォルトで外部であるため、これは必須ではありません。

于 2012-07-13T19:02:48.327 に答える
3

mysql_storage.c関数はとして定義されてstaticいます。これは、ファイルの外部には表示されないことを意味します。削除するstaticと機能するはずです。

于 2012-07-13T19:01:51.157 に答える
3

関数のstaticキーワードは、この関数がこの.objファイルのスコープのみを持つことを意味します。これはおそらく期待したものではありません。static関数の定義と宣言のキーワードを削除します(.hファイルと.cppファイルの両方)

于 2012-07-13T19:02:31.943 に答える
1

関数の前にキーワードstaticを使用すると、関数が定義されているコンパイル単位内でのみ表示されるようになります。関数からstaticキーワードを削除しても、問題はありません。

于 2012-07-13T19:03:32.513 に答える
0

異なるコンパイル単位で関数を使用する場合は、それらを静的と宣言しないでください。

于 2012-07-13T19:03:47.817 に答える