ld: error: undefined symbol: did you mean: extern “C“

没有检索到摘要

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

碰到个问题,先看报错:

FAILURE: Build completed with 2 failures.

1: Task failed with an exception.
-----------
* What went wrong:
Execution failed for task ':shotsync:externalNativeBuildDebug'.
> Build command failed.
  Error while executing process D:\Android\AndroidSdk\cmake\3.10.2.4988404\bin\ninja.exe with arguments {-C E:\work\projects\CameraShotSync\shotsync\.cxx\cmake\debug\armeabi-v7a shotsync socket stcrpc yyjson}
  ninja: Entering directory `E:\work\projects\CameraShotSync\shotsync\.cxx\cmake\debug\armeabi-v7a'
  [1/2] Building CXX object CMakeFiles/shotsync.dir/SyncClient.cpp.o
  [2/2] Linking CXX shared library E:\work\projects\CameraShotSync\shotsync\build\intermediates\cmake\debug\obj\armeabi-v7a\libshotsync.so
  FAILED: E:/work/projects/CameraShotSync/shotsync/build/intermediates/cmake/debug/obj/armeabi-v7a/libshotsync.so
  cmd.exe /C "cd . && D:\Android\AndroidSdk\ndk-bundle\toolchains\llvm\prebuilt\windows-x86_64\bin\clang++.exe --target=armv7-none-linux-androideabi19 --gcc-toolchain=D:/Android/AndroidSdk/ndk-bundle/toolchains/llvm/prebuilt/windows-x86_64 --sysroot=D:/Android/AndroidSdk/ndk-bundle/toolchains/llvm/prebuilt/windows-x86_64/sysroot -fPIC -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D_FORTIFY_SOURCE=2 -march=armv7-a -mthumb -Wformat -Werror=format-security  -std=c++11 -O0 -fno-limit-debug-info  -Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libgcc_real.a -Wl,--exclude-libs,libatomic.a -static-libstdc++ -Wl,--build-id=sha1 -Wl,--no-rosegment -Wl,--fatal-warnings -Wl,--exclude-libs,libunwind.a -Wl,--no-undefined -Qunused-arguments -shared -Wl,-soname,libshotsync.so -o E:\work\projects\CameraShotSync\shotsync\build\intermediates\cmake\debug\obj\armeabi-v7a\libshotsync.so CMakeFiles/shotsync.dir/shotsync.cpp.o CMakeFiles/shotsync.dir/SyncServer.cpp.o CMakeFiles/shotsync.dir/SyncClient.cpp.o  E:/work/projects/CameraShotSync/shotsync/build/intermediates/cmake/debug/obj/armeabi-v7a/libsocket.so E:/work/projects/CameraShotSync/shotsync/build/intermediates/cmake/debug/obj/armeabi-v7a/libstcrpc.so -llog -latomic -lm && cd ."
  ld: error: undefined symbol: rpc_alloc()
  >>> referenced by SyncClient.cpp:27 (E:/work/projects/CameraShotSync/shotsync/src/main/cpp\SyncClient.cpp:27)
  >>>               CMakeFiles/shotsync.dir/SyncClient.cpp.o:(ClientInit)
  >>> did you mean: extern "C" rpc_alloc
  >>> defined in: E:/work/projects/CameraShotSync/shotsync/build/intermediates/cmake/debug/obj/armeabi-v7a/libstcrpc.so
  clang++: error: linker command failed with exit code 1 (use -v to see invocation)
  ninja: build stopped: subcommand failed.
 


* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
==============================================================================

2: Task failed with an exception.
-----------
* What went wrong:
Execution failed for task ':shotsync:externalNativeBuildRelease'.
> Build command failed.
  Error while executing process D:\Android\AndroidSdk\cmake\3.10.2.4988404\bin\ninja.exe with arguments {-C E:\work\projects\CameraShotSync\shotsync\.cxx\cmake\release\armeabi-v7a shotsync socket stcrpc yyjson}
  ninja: Entering directory `E:\work\projects\CameraShotSync\shotsync\.cxx\cmake\release\armeabi-v7a'
  [1/2] Building CXX object CMakeFiles/shotsync.dir/SyncClient.cpp.o
  [2/2] Linking CXX shared library E:\work\projects\CameraShotSync\shotsync\build\intermediates\cmake\release\obj\armeabi-v7a\libshotsync.so
  FAILED: E:/work/projects/CameraShotSync/shotsync/build/intermediates/cmake/release/obj/armeabi-v7a/libshotsync.so
  cmd.exe /C "cd . && D:\Android\AndroidSdk\ndk-bundle\toolchains\llvm\prebuilt\windows-x86_64\bin\clang++.exe --target=armv7-none-linux-androideabi19 --gcc-toolchain=D:/Android/AndroidSdk/ndk-bundle/toolchains/llvm/prebuilt/windows-x86_64 --sysroot=D:/Android/AndroidSdk/ndk-bundle/toolchains/llvm/prebuilt/windows-x86_64/sysroot -fPIC -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D_FORTIFY_SOURCE=2 -march=armv7-a -mthumb -Wformat -Werror=format-security  -std=c++11 -Oz -DNDEBUG  -Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libgcc_real.a -Wl,--exclude-libs,libatomic.a -static-libstdc++ -Wl,--build-id=sha1 -Wl,--no-rosegment -Wl,--fatal-warnings -Wl,--exclude-libs,libunwind.a -Wl,--no-undefined -Qunused-arguments -shared -Wl,-soname,libshotsync.so -o E:\work\projects\CameraShotSync\shotsync\build\intermediates\cmake\release\obj\armeabi-v7a\libshotsync.so CMakeFiles/shotsync.dir/shotsync.cpp.o CMakeFiles/shotsync.dir/SyncServer.cpp.o CMakeFiles/shotsync.dir/SyncClient.cpp.o  E:/work/projects/CameraShotSync/shotsync/build/intermediates/cmake/release/obj/armeabi-v7a/libsocket.so E:/work/projects/CameraShotSync/shotsync/build/intermediates/cmake/release/obj/armeabi-v7a/libstcrpc.so -llog -latomic -lm && cd ."
  ld: error: undefined symbol: rpc_alloc()
  >>> referenced by SyncClient.cpp:27 (E:/work/projects/CameraShotSync/shotsync/src/main/cpp\SyncClient.cpp:27)
  >>>               CMakeFiles/shotsync.dir/SyncClient.cpp.o:(ClientInit)
  >>> did you mean: extern "C" rpc_alloc
  >>> defined in: E:/work/projects/CameraShotSync/shotsync/build/intermediates/cmake/release/obj/armeabi-v7a/libstcrpc.so
  clang++: error: linker command failed with exit code 1 (use -v to see invocation)
  ninja: build stopped: subcommand failed.
 


* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
==============================================================================

* Get more help at https://help.gradle.org

BUILD FAILED in 918ms
41 actionable tasks: 2 executed, 39 up-to-date

其实cmake模块依赖啥的写得没问题,问题就在源码里,对C库的头文件引用,是直接写在了C++文件里,并且没有加extern "C",把C库的头文件引用扔到对应的头文件里,并且包含里在extern "C"里就好了,像这样:

#ifndef CAMERASHOTSYNC_SYNCCLIENT_H
#define CAMERASHOTSYNC_SYNCCLIENT_H
#ifdef __cplusplus
extern "C"{
#endif
#include "libstc-rpc/include/stc_rpc.h"

namespace client {

    int ClientInit(char *host, char const *port = "55555");

    int ClientDestroy();
}


#ifdef __cplusplus
}
#endif
#endif //CAMERASHOTSYNC_SYNCCLIENT_H

而不是像这样:

#include "SyncClient.h"

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include "libstc-rpc/include/stc_rpc.h"

namespace client {

    int sfd;

    int ClientInit(char *host, char const *port) {
        int ret;

        rpc_t* rpc = rpc_alloc();

        return 0;
    }


    int ClientDestroy() {
        int ret;

        return 0;
    }

}

可以参考文章:

extern "C"的用法_fatshaw的博客-优快云博客

https://www.youkuaiyun.com/tags/NtTaAg4sMjAtYmxvZwO0O0OO0O0O.html

<think>好的,我现在需要帮助用户解决ASM文件中出现的两个错误:A45未定义符号和A9语法错误。首先,我要回忆一下汇编语言中常见的错误类型以及可能的原因。 首先,error A45 undefined symbol,这通常表示在汇编代码中引用了一个不存在的符号。可能的原因包括拼写错误、标签未定义,或者没有正确导入外部符号。比如,用户可能在代码中调用了某个子程序或者变量,但该标签并没有在当前的ASM文件中定义,或者在包含头文件时路径不正确,导致符号未被正确引用。我需要检查用户代码中是否有拼写错误,确保所有使用的符号都有定义,或者是否需要在文件中使用EXTERN或IMPORT语句来引入外部符号。 然后是error A9 syntax error,这属于语法错误。汇编语言的语法比较严格,每个汇编器可能有不同的语法要求。比如,指令的格式是否正确,操作数是否匹配,是否使用了错误的伪指令,或者标点符号错误(比如漏掉了冒号或逗号)。此外,还可能是因为在需要使用汇编指令的地方错误地使用了C语言的语法结构,比如在汇编代码中错误地添加了C风格的大括号或者分号。 接下来,我需要考虑用户的具体情况。用户提到之前遇到Keil编译错误,如未定义的符号getBuffPtr和Time1_8_Init,这可能涉及到C与汇编混合编程时的符号导出和导入问题。此外,用户还提到C141错误,这可能与中断服务程序的编写方式有关,特别是51单片机可能需要特定的汇编指令来处理中断向量。 针对这两个错误,我应该分步骤给出解决方案。首先处理A45未定义符号的问题: 1. 检查符号是否存在拼写错误,确保调用和定义的名称完全一致,包括大小写。 2. 确认符号是否在当前的ASM文件中定义,如果没有,是否需要在其他文件或头文件中定义,并通过EXTERN或IMPORT声明引入。 3. 如果是函数或变量,确保在C代码中使用适当的修饰符(如extern "C")来避免名称修饰问题,或者在汇编中正确使用GLOBAL/PUBLIC导出符号。 然后处理A9语法错误: 1. 检查语法是否符合汇编器的要求,例如指令的助记符是否正确,操作数是否合法,标点符号是否正确使用。 2. 检查伪指令的使用是否正确,比如段定义、数据定义等是否遵循汇编器的规范。 3. 确保中断服务程序的中断向量表是否正确设置,例如使用ORG指令定位到正确的中断地址,并正确使用中断号或中断向量名称。 此外,用户可能在混合使用C和汇编时,没有正确地在汇编文件中声明或导出符号,或者在C代码中没有正确声明汇编函数,导致链接时找不到符号。例如,在C中声明一个外部函数,需要在汇编中用PUBLIC或GLOBAL导出该符号,同时在汇编中正确编写函数,确保名称匹配。 最后,建议用户检查ASM文件的语法结构,使用汇编器的文档来验证指令格式,并确保所有外部符号正确导入。可能还需要查看编译器或汇编器的特定要求,例如是否需要使用特定的段名称或属性,或者是否需要在汇编代码中使用特定的语法来定义函数或变量。</think>### 解决ASM文件中Error A45和A9的步骤 #### **1. Error A45: Undefined Symbol(未定义符号)** - **可能原因**: - 符号名称拼写错误(例如`Time1_8_Init`在C代码中声明但未在汇编中导出)[^1]。 - 符号未在汇编文件中定义,或未通过`PUBLIC`/`EXTERN`声明导入导出。 - 符号作用域错误(例如未使用`GLOBAL`或`EXTERN`声明跨文件引用)。 - **解决方法**: 1. **检查符号拼写**:确保汇编代码中引用的符号与定义完全一致(包括大小写)。 2. **声明符号可见性**: - 若符号定义在汇编中,需用`PUBLIC`或`GLOBAL`声明导出: ```assembly PUBLIC Time1_8_Init ; 导出符号 Time1_8_Init PROC ; 定义符号 ; 代码逻辑 Time1_8_Init ENDP ``` - 若符号定义在C代码中,需在汇编中用`EXTERN`声明导入: ```assembly EXTERN getBuffPtr:PROC ; 导入C函数 CALL getBuffPtr ; 调用函数 ``` 3. **检查链接文件配置**:确认汇编文件是否被正确添加到Keil工程中[^1]。 --- #### **2. Error A9: Syntax Error(语法错误)** - **可能原因**: - 指令或伪指令格式错误(如缺少逗号、操作数不匹配)。 - 使用了不支持的语法(例如在51单片机汇编中混用ARM语法)。 - 中断服务程序未按规范编写(如未正确使用中断向量地址)[^2]。 - **解决方法**: 1. **验证指令格式**: - 检查指令操作数是否合法,例如: ```assembly MOV A, #0FFh ; 正确 MOV A 0FFh ; 错误(缺少逗号) ``` 2. **规范中断服务程序**(针对51单片机): - 使用`ORG`指定中断向量地址,并关联中断号: ```assembly ORG 0003h ; 外部中断0向量地址 LJMP EX0_ISR ; 跳转到中断服务程序 EX0_ISR: ; 中断服务程序 ; 代码逻辑 RETI ``` 3. **避免混合语法**: - 确保汇编器与目标芯片架构匹配(如ARM和51单片机的汇编语法不同)。 --- #### **3. 示例修正** 假设原始代码存在以下问题: ```assembly ; 错误示例 EXTERN getBuffPtr MAIN: CALL Time1_8_Init ; Error A45(未定义) MOV A, #0FFh ; Error A9(缺少逗号?) ``` 修正后: ```assembly ; 正确示例 EXTERN Time1_8_Init:PROC ; 显式声明外部函数 PUBLIC MAIN MAIN: CALL Time1_8_Init ; 正确调用 MOV A, #0FFh ; 修正操作数格式 ``` --- ### 相关问题 1. **如何在Keil中正确配置汇编与C混合编程?** (涉及`EXTERN`/`PUBLIC`声明和工程文件设置) 2. **51单片机中断服务程序的汇编语法有哪些特殊要求?** (需使用`ORG`定位中断向量并编写`RETI`返回[^2]) 3. **如何避免ARM汇编与x86/51汇编语法混淆?** (需查阅芯片手册区分指令集和伪操作符)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值