当前位置:  开发笔记 > IOS > 正文

如何解决我在尝试将C++与Assembly链接时遇到的链接器错误?

如何解决《如何解决我在尝试将C++与Assembly链接时遇到的链接器错误?》经验,为你挑选了1个好方法。

我正在尝试链接C++文件和程序集文件.Assembly文件定义了一个名为的C++函数add.我正在使用64位Mac OS.我尝试编译程序时收到以下错误:

Undefined symbols for architecture x86_64:
  "_add", referenced from:
      _main in main-d71cab.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [main.o] Error 1

Makefile文件

hello: main.o hello.o
  g++ main.o hello.o -o hello

hello.o: hello.asm
  nasm -f macho64 hello.asm -o hello.o

main.o: main.cpp
  g++ main.cpp -o main.o   

hello.asm

global add

segment .text
add:
  mov           rax, rdi
  add           rax, rsi
  ret

main.cpp中

#include 

extern "C" int add(int a, int b);

int main(int argc, char* argv[]) {

  int a, b;

  std::cout << "Enter two numbers\n";
  std::cin >> a;
  std::cin >> b;
  std::cout << "Sum of a and b is " << add(a, b) << std::endl;

  return 0;
}

我真的很感激任何帮助.谢谢!



1> Michael Petc..:

在OS/X上,C调用约定是当从对象导出时,函数必须在它们上面有一个下划线(除非它被覆盖),以便对C可见.你说当你放上这个原型时,add正在使用C调用约定extern "C":

extern "C" int add(int a, int b);

这实际上是正确的,但是为了使汇编代码符合您的要求,您还需要确保您的汇编程序函数是全局的并且对C/C++代码可见,它们具有前导下划线.您的汇编程序代码将如下所示:

global _add

segment .text
_add:

你有另一个问题是在你Makefile和你生成的方式main.omain.cpp.

main.o: main.cpp
  g++ main.cpp -o main.o 

这告诉g++编译main.cpp为一个名为的可执行文件main.o.你真正想做的是告诉g++跳过链接到可执行部分,并且输出文件main.o实际上是一个对象.要做到这一点,改变行:

main.o: main.cpp
   g++ -c main.cpp -o main.o

-c选项表示跳过链接阶段(生成可执行文件并只输出稍后将链接的对象).

如果没有这个改变,它会尝试制作main.o,它认为你想要一个可执行文件,并且找不到该函数,_add因为它不在它知道的文件中.它在,hello.o但命令g++ main.cpp -o main.o不知道.

推荐阅读
可爱的天使keven_464
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有