Неопределенная ссылка при использовании g ++ для компиляции - PullRequest
1 голос
/ 09 сентября 2010

Я получаю следующую ошибку p.c использует некоторые функции, реализованные в md4.c. p.c, когда скомпилирован с gcc works но он не работает с g ++, выдает неопределенную ошибку метода. Я что-то упускаю из виду?

[prafulla@ps7374 sample] $g++ -c -o md4.o md4.c 
[prafulla@ps7374 sample] $gcc -c -o md4.o md4.c
[prafulla@ps7374 sample] $g++ p.c md4.o
p.c: In function ‘int main()’:
p.c:5: warning: deprecated conversion from string constant to ‘char*’
/tmp/ccxE4q1J.o: In function `main':
p.c:(.text+0x3b): undefined reference to `MD4Init(MD4_CTX*)'
p.c:(.text+0x57): undefined reference to `MD4Update(MD4_CTX*, unsigned char*, unsigned int)'
p.c:(.text+0x6b): undefined reference to `MD4Final(unsigned char*, MD4_CTX*)'
collect2: ld returned 1 exit status
[prafulla@ps7374 sample] $gcc p.c md4.o

Вот мой make-файл

sample.out: sample.cc md4.o Makefile                                                                                                                         
            g++ -o sample.out sample.cc md4.o                                                                                                                              
            ./sample.out                                                                                                                                     
test.o: p.c                                                                                                                                                  
        g++ p.c md4.o                                                                                                                                        

md4.o:      md4.c md4.h                                                                                                                                      
            gcc -c -o md4.o md4.c   

1 Ответ

4 голосов
/ 09 сентября 2010

Поскольку C ++ поддерживает перегрузку функций, компилятор C ++ должен убедиться, что компоновщик видит два разных имени для void foo(int) и void foo(float).Наиболее распространенный способ сделать это - закодировать информацию о параметрах в имена, представленные компоновщику.Поскольку C не перегружен, компилятору также нет необходимости включать информацию о параметрах в имена, представленные компоновщику.

Если вы сейчас наивно пытаетесь связать объектный файл C и C ++,компоновщик не сможет разрешить все имена, потому что объектные файлы используют другую схему именования для имен, которые им нужны и / или экспортируются.

Поскольку довольно часто используется код C из C ++В программе C ++ есть механизм, сообщающий компилятору, что некоторые функции должны использовать схему именования C вместо схемы C ++: эти функции объявляются как extern "C" int bar() или, если у вас есть набор функций C:

extern "C" {
  /* Function declarations here */
}

И там, где написано «Объявления функций здесь», вы можете просто использовать #include для извлечения заголовка C (хотя бесконечно лучше подготовить сам заголовок для использования как в C, так и в C ++).

Чтобы подготовить заголовок для использования в C и C ++, сначала убедитесь, что он не использует ключевые слова, специфичные для C ++ (например, class или new), иru Вы можете добавить в заголовок следующую мантру:

/* Include guard goes here */

#ifdef __cplusplus
extern "C" {
#endif

/* original content of the header */

#ifdef __cplusplus
}
#endif

/* #endif of the include guard here */
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...