首页
学习
活动
专区
圈层
工具
发布

【C++报错已解决】 “Undefined Reference“

这个错误提示通常意味着编译器找不到某个符号的定义,这个符号可能是函数、变量或者一个类型。别担心,今天我将分享我是如何解决这个问题的。通过这个案例,你将学会如何快速定位并解决类似的报错。...一、问题描述 1.1 报错示例 让我们来看一个 C++ 的例子,这个例子中包含了 “Undefined Reference” 报错: #include iostream> int main() {...main 函数中找不到 add 函数的定义。...add.cpp -o program 步骤二:确保所有文件都正确链接 如果 add 函数定义在另一个文件中,确保在编译时将这个文件包含在内: g++ main.cpp -o program 如果你使用的是...gcc 而不是 g++,确保使用 -l 前缀来链接所需的库: gcc main.cpp -o program -lm 三、总结 解决 “Undefined Reference” 报错的关键是确保所有的符号都有定义

54710

从 Java 到 C++:用 JNI 实现字符串拼接全解析

JNI.java选项生成 C/C++ 标头并将其放置在指定的目录中(在上面的示例中, '.'表示当前目录)。...在JDK 8之前,需要使用javac编译Java程序并使用专用的javah实用程序生成C/C++标头,如下所示。 javah实用程序在 JDK 10 中不再可用。...第四步:编译动态链接库使用 C++ 编译器(如 g++)生成动态链接库。确保包含 JNI 头文件和平台相关的路径。...-shared告诉编译器生成一个共享链接库,而非普通的可执行文件。此选项会自动处理链接时的符号导出。-o指定输出文件名。...在 Linux 下,动态链接库的命名规则为 libxxx.so 的形式,例如 libhelloWorld.so。-I指定头文件搜索路径,用于告诉编译器 JNI 所需的头文件所在目录。

64130
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    C++如何调用写好的C接口?

    一个头文件test.h #ifndef _TEST_H #define _TEST_H void print(int a,int b); #endif C++文件调用C函数 #include iostream...那么g++编译器为什么找不到print(int,int)呢,其实在我们学C++重载的时候就提到过C++底层的编译原理。...原因分析 test.c我们使用的是C语言的编译器gcc进行编译的,其中的函数print编译之后,在符号表中的名字为 print,通过nm查看.o文件. $ gcc -c test.c $ nm test.o...print)的名字,发现找不到,所以会提示“未定义的引用” $ g++ -c test.c $ ls main.cpp makefile test.c test.h test.o $ nm test.o...extern “C” ,这个时候,g++编译器就会按照C语言的链接方式进行寻找,也就是在符号表中寻找print(这才是C++兼容C),这个时候是可以找到的,是不会报错的。

    1.4K10

    未来已来:C++ modules初探

    你好,我是乐哥,一个从事C/CPP开发十几年的老鸟~~ 在C++中,编译器在编译某个源文件时确实需要查看其中所有需要调用的函数的声明。...这是因为C++是一种静态类型语言,编译器在编译阶段需要了解函数的签名(返回类型、函数名、参数类型和顺序等信息),以便进行类型检查和生成正确的机器代码。...只有这样编译器才能生成适当的代码来调用该函数。...如果某个头文件定义忘记包含#pragma once或者ifndef 等,就会报错,这样的话,我们需要查找所有的代码来定位这个原因,而有了module之后,虽然不能完全避免,但是可以在一定程度上减轻,因为其必须包含当前所需要的...,如果要使用gcc的话,需要手动编译iostream: g++ -std=c++20 -fmodules-ts -xc++-system-header iostream g++ -std=c++20 -

    59210

    简单的Python调用C++程序

    编辑:小白学视觉 Python调用C/C++程序的方法 最近写BUG的时候遇到python计算很慢的情况,于是调研了一波在python中嵌入C++程序的方法,记录一下,便于查询。...,在g++以C++方式编译时编译器会给函数的名称附加上额外的信息,这样ctypes模块就会找不到g++编译生成的函数。...因此,要让g++按照C语言的方式编译才可以找到生成的函数名。让编译器以C语言的方式编译就要在代码中使用extern关键字将代码包裹起来。...C++源文件:cpp_called.cpp //Python调用c++(类)动态链接库 #include <iostream> using namespace std; class TestLib...-- --> obj.display(a); } } 在命令行或者终端输入编译命令: g++ -o libpycallcpp.so -shared -fPIC cpp_called.cpp

    1.4K20

    错误使用 C++ 模板特化产生的坑

    问题是这样的: 有一个名为 A 的库,包含如下的头文件 a.h 和代码文件 a.cc // a.h #pragma once #include iostream> template ...这听起来很奇怪是吧,不过确实是这样: 链接方式 1: g++ -c a.cc g++ -o main main.cc a.o 链接方式 2: g++ -c a.cc ar -r a.a a.o g++...简单来说,正确的模板特化写法应该是将特化声明写在头文件里,必须在使用该模板之前出现对应声明,否则编译器就会进行自动实例化: // a.h #pragma once #include iostream>...为了解决这个问题,我们将编译过程再改一下,变成这样: g++ -c a.cc g++ -c main.cc g++ -o main main.o a.o 此时,编译过程会产生 main.o 和 a.o...至此,这次的问题算是可以完整地合理解释了: 链接的时候,.o 文件必然链接,.a 文件只会在符号找不到的时候链接 模板自动实例化出来的版本是弱符号,手写特化的是强符号,当二者同时参与链接时会选择强符号而不是产生冲突

    92030

    简单的Python调用C++程序

    Python调用C/C++程序的方法 最近写BUG的时候遇到python计算很慢的情况,于是调研了一波在python中嵌入C++程序的方法,记录一下,便于查询。...,在g++以C++方式编译时编译器会给函数的名称附加上额外的信息,这样ctypes模块就会找不到g++编译生成的函数。...因此,要让g++按照C语言的方式编译才可以找到生成的函数名。让编译器以C语言的方式编译就要在代码中使用extern关键字将代码包裹起来。...C++源文件:cpp_called.cpp //Python调用c++(类)动态链接库 #include <iostream> using namespace std; class TestLib...-- --> obj.display(a); } } 在命令行或者终端输入编译命令: g++ -o libpycallcpp.so -shared -fPIC cpp_called.cpp

    96820

    C++调用C接口

    函数 #include iostream> using namespace std; #include "p.h" int main() { cout<<"现在调用C语言函数\n";...原因分析 p.c我们使用的是C语言的编译器gcc进行编译的,其中的函数print 编译之后,在符号表中的名字为 _print 我们链接的时候采用的是g++进行链接,也就是C++链接方式,程序在运行到调用...print函数的代码时,会在符号表中寻找_print_int_int(是按照C ++的链接方法来寻找的,所以是找_print_int_int而不是找_print )的名字,发现找不到,所以会t提示...“未定义的引用” 此时如果我们在对print的声明中加入 extern “C” ,这个时候,g ++编译器就会按照C语言的链接方式进行寻找,也就是在符号表中寻找_print ,这个时候是可以找到的,...{ void print(int a,int b); } #endif 修改后再次执行命令 gcc -c p.c g++ -o main main.cpp p.o .

    2.1K20

    云课五分钟-0Cg++默认版本和升级-std=c++17

    这些资源通常会提供关于编译器特性和标准的详细说明。 g++的官方网站是GNU编译器集合(GNU Compiler Collection,简称GCC)的官网。GCC包含了g++编译器。...然而,实际上gcc也可以编译C++代码,只是需要手动链接所需的库。 关于g++和gcc的其他方面的区别: 库的支持: 使用g++编译时,它会默认链接标准C++库。...静态链接将所有库和代码嵌入到最终的可执行文件中,而动态链接则是在运行时加载所需的库。 插件与扩展 gcc和g++支持插件和扩展,这可以增强编译器的功能。...以下是一个简单的C++代码示例,你可以使用g++进行编译: cpp复制代码 #include iostream> int main() { std::cout 的例子来说明这一点: 创建一个简单的C++程序,命名为test.cpp: cpp复制代码 #include iostream> int main() { std::cout

    2K40

    C++雾中风景15:聊聊让人抓狂的Name Mangling

    比如:函数的重载,或通过不同程序块与命名空间变量与函数的重名。 而在出现变量或函数名相同的情况下,编译器进行代码编译时需要保证变量与函数的签名的全局唯一性。...如果无法进行上述保证,在链接阶段就会产生链接的二义性,会导致编译器不知道应该如何取用正确的变量与函数符号的内存地址。...(由于在C++的标准之中,并未强制规定Name Mangling的实现机制,所以不同的编译器在不同的平台上实现是完全不同的。...我们来看看通过gcc和g++的编译结果有和不同吧,首先我们定义一个简单的函数sum: int sum(int a, int b) { return a + b; } g++的编译结果 _Z3sumii...3.2 extern "C" 所以通过C++定义的函数需要被C语言调用时,需要通过keyword:extern C来显式的让编译器明白需要使用C语言的Name Mangling规则,以便编译器链接时能够正确的识别函数签名来定位到所需的函数

    1.1K41

    模板与分离编译模式

    ***func.h***/ template void func(const T&); /***end func.h***/ /***func.cpp***/ #include iostream...也就是说,在main.obj中也找不到模板函数func的实现代码。这样,在连接的时候就会出现func没有定义的错误。...也就是说,在func.cpp里定义函数模板的时候,将函数模板头写成: export template void func(const T& t); 这样做的目的是告诉编译器,这个函数模板可能再其他源文件中被实例化...这是一个对程序员来说负担最轻的解决办法,但是,目前几乎所有的编译器都不支持关键字export,包括VC++和g++。 3.3显示实例化 显示实例化也称为外部实例化。...当类模板的成员函数的实现定义在源文件中,通过模板类的对象调用成员函数时也会出现找不到函数定义的错误,可以使用同样的方法解决,不再赘述。

    92720

    蓝桥ROS机器人之C++基础开发第一个程序

    0.8几个常见的 C++ 问题 0.9配置编译器:构建配置 0.10配置编译器:编译器扩展 0.11配置编译器:警告和错误级别 0.12配置编译器:选择语言标准 C++ 基础 1.1语句和程序结构...1.2注释 1.3对象和变量简介 1.4变量赋值和初始化 1.5iostream 简介:cout、cin 和 endl 1.6未初始化的变量和未定义的行为 1.7关键字和命名标识符 1.8...该程序应产生以下输出(假设我输入 4 作为输入): 输入一个整数:4 这个数字的两倍是:8 不怎么好的代码: #include iostream> // worst version int main...这些教程中提出的解决方案很少有第一次就很好用。相反,它们是不断改进的结果,直到找不到其他可以改进的地方。在许多情况下,读者仍然会发现许多其他建议作为改进!...g++编译,注意使用c++11 g++ -std=c++11 multiply2.cpp -Fin-

    46310

    头文件是必须的吗?跟一跟编译过程~~~

    预处理阶段会将#include包含的文件直接插入到源文件.cpp中去。头文件实际上并不会被编译,编译器只会编译源文件。只是在编译之前,会将源文件中#include包含的文件在源文件中展开。...#include iostream> #include 接下来再做一个测试: 如上图结构的文件,这次我手动把#include在源文件中展开: 如上图,这也是ok的,可以编译成功...声明变量可以告诉编译器这个变量类型是什么,占多少个字节。声明函数则可以告诉编译器函数名是什么、返回类型是什么、参数个数、参数类型是什么。不声明就使用,别人怎么知道func是什么东西呢?...上面的ld是链接器,是一个可执行程序,它的输入是一个或多个目标文件,如上面指令中的main.o。 也就是说,目标文件main.o中引用了func(),但链接器找不到它的定义。...即,链接器在面对一个目标文件时,如果碰到里面有未定义的引用,会在其他目标文件中查找,如果找不到,则报错“undefined reference to”。如果找到有且仅有一个,则pass。

    2.5K10

    Hello World背后的秘密:详解 C++ 编译链接模型

    #include 的本质#include iostream> 这条语句的真正作用是将iostream文件的内容原封不动地复制到当前文件中。...可以通过以下命令查看预处理结果:g++ -E main.cpp -o main.ii查看生成的main.ii文件,你会惊讶地发现原本7行的代码变成了数万行!...头文件包含机制头文件包含有两种形式:#include iostream> // 系统头文件,编译器在系统路径中查找#include "myheader.h" // 用户头文件,编译器先在当前目录查找...编译的详细过程可以使用以下命令生成汇编代码:g++ -S main.ii -o main.s生成的汇编代码示例(x86架构): .section __TEXT,__text,regular,...编译效率:修改实现文件只需重新编译该文件,而不必重新编译所有包含其头文件的文件抽象与实现分离:头文件提供接口,实现文件提供具体实现减少重复:通过包含guards避免多次包含同一头文件One Definition

    16510

    鹅厂面试题|“你知道C++从源文件到可执行代码的过程吗?”

    以Hello World为例进行说明 首先我们编写一个cpp源程序:test.cpp #include iostream> using namespace std; int main() {...cout << "hello world" << endl; return 0; } 使用g++命令行进行编译: g++ -o test test.cpp 该命令行是利用gcc编译器将源程序test.cpp...②编译阶段:将经过预处理后的预编译文件转换成特定汇编代码,生成汇编文件(.s文件). ③汇编阶段:将编译阶段生成的汇编文件转化成机器码,生成可重定位目标文件 (.o或.obj文件) ④链接阶段:将多个目标文件及所需要的库连接成最终的可执行目标文件...最基本的静态链接如图所示: g++命令行如下: g++ test.o -o test 动态链接 g++ tets.o -static -o test静态链接 2种都可生成可执行文件,前者文件只包含文件名...#include"",先从当前目录开始寻找头文件, 找不到再从标准库中寻找头文件。

    1.1K20

    C++之类型转换函数

    为此我们这里总结了一副隐式类型转换的图: 下面我们来几个隐式转换的例子: 代码版本一: #include iostream> #include  int main() {      ...其实这里编译器把short和char类型的都转换int类型了,所以最终两个int数据相加,所占的内存大小就是int类型了。...关键字杜绝编译器的转换尝试 转换构造函数被explicit修饰只能进行显示转换(也就是强制类型转换) 代码实践一: #include iostream> #include  class...+ test.cpp root@txp-virtual-machine:/home/txp#  注: 与转换构造函数具有同等的地位 使得编译器有能力将对象转化为其它类型 编译器能够隐式的使用类型转换函数...2、类类型之间的转换: 这个问题也是之前我们上面简单的测试,不能进行类类型之间的转换;现在我们学习了类型转换函数,是可以进行转换的: 代码版本一: #include iostream> #include

    78020

    简单的Python调用C++程序

    重磅干货,第一时间送达 Python调用C/C++程序的方法 最近写BUG的时候遇到python计算很慢的情况,于是调研了一波在python中嵌入C++程序的方法,记录一下,便于查询。...,在g++以C++方式编译时编译器会给函数的名称附加上额外的信息,这样ctypes模块就会找不到g++编译生成的函数。...因此,要让g++按照C语言的方式编译才可以找到生成的函数名。让编译器以C语言的方式编译就要在代码中使用extern关键字将代码包裹起来。...C++源文件:cpp_called.cpp //Python调用c++(类)动态链接库 #include <iostream> using namespace std; class TestLib...-- --> obj.display(a); } } 在命令行或者终端输入编译命令: g++ -o libpycallcpp.so -shared -fPIC cpp_called.cpp

    56110

    C和C++编译工具的基本使用方法

    而GCC下面有两个比较常用的工具就是gcc(GUN C Compiler)和g++(GUN C++ Compiler),即c语言编译器和c++编译器。我通常用gcc编译c代码,用g++编译c++代码。...g++ 编译器的使用 (1)编译过程 第一步:预处理 Pre-processing,生成.i 文件 # -E 选项指示编译器仅对输入文件进行预编译 g++ -E test.cpp -o testr.i...-o test.s 第三步:汇编-Assembing,生成.o 文件 # -c 选项告诉 g++ 仅把源代码编译为机器语言的目标代码 # 缺省时 g++ 建立的目标代码文件有一个 .o 的扩展名 g...g++ -O2 test.cpp 示例 创建一个效率低下的代码块inefficency.cpp,添加以下内容 #include iostream> using namespace std; int...我们可以使用再次使用 time 命令计算执行程序所需的时间,可以看到明显的时间区别,如下结果 pan@pan-PC:~/Work/src/cmake/src$ time .

    1.5K10
    领券