2013-04-29 53 views
1

我在编译和链接用汇编语言编写的库与我的C++程序代码时遇到了一些麻烦。在我的情况下,它是使用avr-gcc套件的AVR微控制器,但我想这个问题一般适用于GCC。GCC链接/符号名称与C++和汇编文件混在一起

我可以得到的.o从C++源代码和汇编建文件,但将它们连接提供了错误:

> avr-gcc -mmcu=attiny84 -lm -o obj\AvrTest.elf obj\Main.o obj\i2cmaster.o 
obj\Main.o: In function `main': 
Main.cpp:(.text+0x0): undefined reference to `i2c_init()' 

这里的尤伯杯简单Main.cpp代码:

#include "i2cmaster.h" 
void main() { 
    i2c_init(); 
    while (true) { 
    } 
} 

i2cmaster.h定义功能原型如下:

extern void i2c_init(void); 

而在组合呃文件,i2cmaster.S,该功能是:

.global i2c_init 
.func i2c_init 
i2c_init: 
cbi SDA_DDR,SDA  ;release SDA 
cbi SCL_DDR,SCL  ;release SCL 
cbi SDA_OUT,SDA 
cbi SCL_OUT,SCL 
ret 
.endfunc 

的链接似乎是一个没有脑子 - 但我得到的引用错误。我注意到了Main.cpp产生的汇编代码出来是这样的:

.global main 
.type main, @function 
main: 
rcall _Z8i2c_initv 
.L2: 
rjmp .L2 
.size main, .-main 

我怀疑的问题是,i2c_init变得_Z8i2c_initv通过一些名字改编过程中,我不明白,这_Z8i2c_initv可以不再与匹配i2cmaster.o目标文件中未被修复的i2c_init符号。

有没有人了解编译过程,以及如何在编译/汇编期间抑制它,以便这些模块可以相互交谈?或者我可能做错了什么?

回答

4

好的,解决了。显然,符号修改是一个C++的事情,并且i2c库没有设置为正确使用C++。能够使用以下方法修复它:

extern "C" { 
    #include "i2cmaster.h" 
}; 
void main() { 
    i2c_init(); 
    while (true) { 
    } 
} 
+1

为什么在编写C++时为您的问题C添加标签? – 2013-04-29 05:37:30

+0

我在这个程序中没有使用任何C++特性,所以认为它等于C. – QuadrupleA 2013-04-29 06:36:36

+0

不是。 C不是C++的子集。 – 2013-04-29 12:21:24