今天发现一个问题,与inline有关,也与编译时候是不是优化有关。

大概问题可以用下面的代码来描述:

先写一个libtest1,代码如下

libtest1.h

#ifndef LIBTEST_H
#define LIBTEST_H class Test{
public:
inline void fun1()const;
void fun2()const;
};
#endif //!LIBTEST_H

libtest1.cpp

#include <stdio.h>
#include "libtest.h" void Test::fun1()const
{
puts("fun1");
} void Test::fun2()const
{
fun1();
puts("fun2 call fun1");
}

编译为动态库,使用命令为:gcc -shared -fpic libtest.cpp -o libtest1.so

然后第二个动态库libtest2,代码如下

#include "libtest.h"

extern "C" void fun3()
{
Test t;
t.fun1();
t.fun2();
}

编译命令为:gcc -shared -fpic libtest2.cpp -o libtest2.so -Wl,-rpath=. -L. -ltest1

然后写测试代码,运行时加载libtest2.so,然后调用fun3函数。代码如下

#include <stdio.h>
#include <dlfcn.h> typedef void (FuncType)(); int main()
{
//void* p = dlopen("./libtest2.so",RTLD_NOW);
void* p = dlopen("./libtest2.so",RTLD_LAZY);
if(p == NULL){
printf("dlopen libtest2.so failed:%s\n",dlerror());
return 0;
}
FuncType* f1 = (FuncType*)dlsym(p,"fun3");
if(f1 == NULL){
printf("dlsym fun3 failed:%s\n",dlerror());
return 0;
}
f1();
dlclose(p);
return 0;
}

编译执行结果如下:

/home/o/sopath [o@o-pc] [13:40]
> gcc test.cpp -o test -ldl /home/o/sopath [o@o-pc] [13:41]
> ./test
fun1
fun1
fun2 call fun1

看起来好像没有问题,但是这里编译的时候都没有进行优化,使用的默认选项,如果我们编译命令修改一下,则就变了

/home/o/sopath [o@o-pc] [13:34]
> gcc -shared -fpic libtest.cpp -o libtest.so -O3
/home/o/sopath [o@o-pc] [13:41]
> ./test
./test: symbol lookup error: ./libtest2.so: undefined symbol: _ZNK4Test4fun1Ev

这时候就找不到fun1这个函数了,使用strings libtest1.so也确实找不到。但是如果把fun1前面的inline去掉,就没有问题了。

gcc下inline的一个问题的更多相关文章

  1. Ubuntu系统下的第一个console程序

    进入自己喜欢的目录,前面步骤和windows基本一致,只简单描述下 执行 dotnet new 然后执行 dotnet restore 然后执行 dotnet run 第一次未编译,会自动编译,然后可 ...

  2. time模块目录下自己建立一个名为log的文件夹

    使用python调用ping命令,然后在日志中记录ping的结果,用来监测网络连通情况. 代码: [python]from time import *from subprocess import *w ...

  3. MinGW GCC下sleep()函数问题

    在MinGW GCC下编译带sleep()函数的测试程序,不管是包含了unistd.h头文件,还是stdio.h.stdlib.h头文件,就是找不到该函数的定义!在linux下,sleep()函数的头 ...

  4. 在linux下,查看一个运行中的程序, 占用了多少内存

    1. 在linux下,查看一个运行中的程序, 占用了多少内存, 一般的命令有 (1). ps aux: 其中  VSZ(或VSS)列 表示,程序占用了多少虚拟内存. RSS列 表示, 程序占用了多少物 ...

  5. GCC下32位与64位机器类型变量所占字节数

    GCC下32位与64位机器类型变量所占字节数 在C语言中,编译器一般根据自身硬件针对类型变量来选择合适的字节大小,下面列举一下在GCC编译器下32位机器与64位机器各个类型变量所占字节数目: C语言 ...

  6. python3 selenium 随机选择同一类型下的某一个元素

    使用场景: 如上图所示,有时候,我们测试的时候,不会每个方向都选择一遍,也不能每次都选择一个方向,这个时候就需要每次运行用例的时候,随机选择一个方向来测试 使用方法: random.randint() ...

  7. npm 是node.js下带的一个包管理工具

    npm 是node.js下带的一个包管理工具          npm install -g webpack webpack是一个打包工具 gulp是一个基于流的构建工具,相对其他构件工具来说,更简洁 ...

  8. 找到div下的第一个ul

    $("div#div的id ul li a")//选择的是div下 ul下所有li下的所有a标签 $("div#div的id").children(" ...

  9. 在Android系统中修改Android.mk使其同时编译rgb2565和rgb2888(向out/host/linux-x86/bin/下新增加一个工具命令)【转】

    本文转载自:http://blog.csdn.net/mu0206mu/article/details/7514559 在Android系统中修改android.mk使其同时编译rgb2565和rgb ...

随机推荐

  1. C# mongoDB Driver 使用对象方式查询语法大全

    #region 查询方法 /// <summary> /// 获取单个对象 /// </summary> /// <typeparam name="T" ...

  2. python3 使用SimpleHTTPServer搭建web服务器

    刚刚萌发了一个念头,要用python来做个web服务器,秀出自己的网页.于是,开始了我的搭建web服务器之旅. 首先,如果不想使用Apache.IIS,那就需要一个HTTP服务,而python自带了一 ...

  3. KNN分类算法补充

    KNN补充: 1.K值设定为多大? k太小,分类结果易受噪声点影响:k太大,近邻中又可能包含太多的其它类别的点. (对距离加权,可以降低k值设定的影响) k值通常是采用交叉检验来确定(以k=1为基准) ...

  4. vi中批量加注释

    用v进入virtual模式 按Control+v(win下面ctrl+q)进入列模式 上下键来进行选择 I进行输入(shift+i) 按两次ese键

  5. 【目录】LeetCode Java实现

    这里记录一下自己刷的LeetCode题目. 有些博客用英文阐述自己的思路和收获,相当于练习一下英文的表达能力. 比较好的题目有加粗. 1. Two Sum 3. Longest Substring W ...

  6. Linux学习之常用网络通信命令与shell简单应用技巧(四)

    (一)常用网络通信命令 (1)ping命令 (2)write命令 (3)wall命令 (4)ifconfig命令 (5)shutdown命令 (6)reboot命令 (二)shell简单应用技巧 (1 ...

  7. JS高级-原型等概念深入理解

    一 数据类型: 基本(值)数据类型: string number undefined null boolean 对象(引用)类型 [ 查找对象的属性时,会查找原型链 设置属性时,一般在构造函数里面设置 ...

  8. 电商sku商品推荐

    1.逻辑回归LR进行实时离线三级品类训练. 2.通过用户对于实时.离线三级品类的偏好进行召回. 3.通过人的特征.sku特征.人sku交互特征.以及位置手机特征通过gbdt模型进行点击量预估.

  9. 洛谷.4015.运输问题(SPFA费用流)

    题目链接 嗯..水题 洛谷这网络流二十四题的难度评价真神奇.. #include <queue> #include <cstdio> #include <cctype&g ...

  10. Python图形编程探索系列-07-程序登录界面设计

    设计任务 初步设计程序登录界面,详细分析设计步骤. 程序详细分析 基本框架设计 import tkinter as tk import tkinter.messagebox root = tk.Tk( ...