[英]“Undefined reference to” error even function is declared and defined
我有這些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
。 因此,它不應引發未定義的參考錯誤。 這里有什么問題?
您將函數mysql_storage_init
聲明為static
,這意味着它們具有內部鏈接 -這意味着它們對其他翻譯單元不可見。
由於需要從其他目標文件中調用它們,因此應改為在它們的聲明和定義中省略static
關鍵字,以聲明它們具有外部鏈接 。 頭文件中的原型可以選擇將其聲明為extern
,但這不是必需的,因為默認情況下鏈接是外部的。
您的mysql_storage.c函數定義為static
,這意味着它們在文件外部不可見。 去除static
,它應該可以工作。
函數的static
關鍵字表示此函數僅具有此.obj文件的范圍,這可能與您期望的不一樣。 刪除用於函數定義和聲明的static
關鍵字(.h和.cpp文件)
在函數之前使用關鍵字static可以確保它們僅在定義的編譯單元中可見。 如果從函數中刪除static關鍵字,則應該沒有問題。
如果打算在不同的編譯單元中使用函數,則不應將其聲明為靜態。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.