GCC链接/符号名称修改与C ++和汇编程序文件

时间:2013-04-29 03:20:11

标签: c++ gcc assembly avr-gcc name-mangling

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

我可以从C ++源代码和程序集中获取.o文件,但链接它们会产生错误:

> 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无法再与未受损的i2c_init匹配i2cmaster.o目标文件中的{1}}符号。

是否有人了解修复过程,以及如何在编译/汇编期间抑制它,以便这些模块可以相互通信?或者其他任何我可能做错了?

1 个答案:

答案 0 :(得分:4)

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

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