精华内容
下载资源
问答
  • (1)开源的class_loader生成so文件,作为插件生成、加载等的基础; (2)插件基类,包括标签生成器基类、传感器数据采集基类,依赖class_loader,目的是为具体的插件提供头文件; (3)标签生成器插件,用户自己...

    这一段一直在整插件管理框架的事情,整个框架分成几层:

    (1)开源的class_loader生成so文件,作为插件生成、加载等的基础;

    (2)插件基类,包括标签生成器基类、传感器数据采集基类,依赖class_loader,目的是为具体的插件提供头文件;

    (3)标签生成器插件,用户自己实现genLabel函数,通过用户逻辑来控制输出的标签的内容、长度等,这个插件依赖于class_loader和插件基类;

    (4)传感器数据采集插件,也是以class_loader为基础,同时依赖标签生成器和插件基类;

    (5)插件管理框架,将所有的插件管理起来,实际上直接依赖于class_loader和插件基类。

    现在按照上述层次关系,依次编译安装。但在使用过程中,例如对于插件管理框架,用户想着我只是用你的插件管理框架,我引入该框架的.so文件即可,至于你依赖谁,我并不关心,我也不应该知道,我更不应该引入这些so文件。这是因为在默认情况下,库依赖项是传递的。当目标A 链接到目标B 时,链接到A 的库也会出现B 的链接线上。

    上述几个工程都在同一个目录下,属于平级关系,如下图所示。

    我们在编译完插件管理框架后,使用ldd查看链接关系,发现所有库都是链接上的。

    对应的cmakelists文件如下:

    cmake_minimum_required(VERSION 3.4.2)
    
    project(pluginManager CXX)
    
    # Default to C++14
    if(NOT CMAKE_CXX_STANDARD)
      set(CMAKE_CXX_STANDARD 14)
    endif()
    if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
      add_compile_options(-Wall -Wextra -Wpedantic -pthread -lboost_filesystem)
    endif()
    
    include(../micros.cmake)
    set(LINK_DIR ./lib ) # can not be obsolute path
    set(CONSOLE_DIR /lib/x86_64-linux-gnu/)
    set(POCO_DIR /usr/lib/x86_64-linux-gnu/)
    set(CLASS_LOADER_LIB /opt/micros/1.0.1/third-party/class_loader/lib)
    message("aaaaaaaaaa" ${CMAKE_INSTALL_PREFIX})
    set(${PROJECT_NAME}_SRCS src/pluginManager.cpp)
    set(${PROJECT_NAME}_HDRS include/micros_pluginmanager/pluginManager.h)
    
    include_directories( ./include /usr/include)
    
    include_directories(/opt/micros/1.0.1/include)
    include_directories(${CMAKE_INSTALL_PREFIX}/third-party/class_loader/include)
    link_directories(${CMAKE_INSTALL_PREFIX}/lib 
    #${CMAKE_INSTALL_PREFIX}/third-party/class_loader/lib
    #${CLASS_LOADER_LIB}
     ${CMAKE_TMP_OUTPUT_SO_PATH}
     )
    SET(LIBRARY_OUTPUT_PATH ${CMAKE_TMP_OUTPUT_SO_PATH})
    
    link_directories(${LINK_DIR}
                     ${CONSOLE_DIR} 
                     ${POCO_DIR} 
                    /opt/micros/1.0.1/lib/plugins
                     ${CLASS_LOADER_LIB})
    
    #插件基类对应的so文件
    add_library(label_sensor.0.1.0 SHARED IMPORTED)
    set_property(TARGET label_sensor.0.1.0 PROPERTY IMPORTED_LOCATION "/opt/micros/1.0.1/lib/plugins/liblabel_sensor.0.1.0.so")
    #class_loader对应的so文件
    add_library(libmicros_scene_classloader.0.1.0 SHARED IMPORTED)
    set_property(TARGET libmicros_scene_classloader.0.1.0 PROPERTY IMPORTED_LOCATION "/opt/micros/1.0.1/third-party/class_loader/lib/libmicros_scene_classloader.0.1.0.so")
    
    
    add_library(micros_scene_pluginmanager.0.1.0 SHARED ${${PROJECT_NAME}_SRCS} ${${PROJECT_NAME}_HDRS})
    
    target_link_libraries(micros_scene_pluginmanager.0.1.0  optimized
      label_sensor.0.1.0
      micros_scene_classloader.0.1.0
      
    ) 
    #安装so文件到/opt/xxx/lib/目录下
    install(TARGETS micros_scene_pluginmanager.0.1.0 LIBRARY DESTINATION lib/)
    install(DIRECTORY include/  DESTINATION include/) 

    当我们安装后,也就是执行sudo make install之后,发现插件基类库和class_loader库并没有链接上去:

    查了不少原因,尝试了不少方法还是不行。最后,我们思考一下,安装前后的区别是什么?是搜索路径:

    问题

    如果ldd命令没有找到对应的共享库文件和其具体位置?

    可能是两种情况引起的:

    1)共享库没有安装在该系统中;

    2)共享库保存在/etc/ld.so.conf文件列出的搜索路径之外的位置。

    通常情况下,许多开源代码的程序或函数库都会默认将在即安装到/usr/local目录下的相应位置(如:/usr/local/bin 或 /usr/local/lib)以便于系统自身的程序或函数库相区别。而许多linux系统的/ect/ld.so.conf 文件中默认又不包含 /usr/local/lib 。因此出现安装了共享库,但是却无法找到共享库的情况。

    解决办法:
    检查/etc/ld.so.conf文件,如果其中缺少自己编译的被依赖的库的目录,就添加进去;
    注意:在修改了/etc/ld.so.conf 文件或者在系统中安装了新的函数库之后,需要运行命令 ldconfig ,该命令用来刷新系统的共享库缓存,即 /etc/ld.so.cache 文件。为了减少共享库系统的库搜索时间,共享库系统维护了一个共享库so名称的缓存文件 /etc/ld.so.cache 。 因此,在安装新的共享库之后,一定要运行 ldconfig刷新该缓存。

    我们添加插件基类库和class_loader库文件所在路径到/etc/ld.so.conf文件中,如下图所示:

    然后执行sudo /sbin/ldconfig使上述修改生效。

    重新安装插件管理框架库文件,然后ldd查看:

    至此,链接库找不到的问题解决。

    虽然上面的问题解决了,但是给我留下一个更大的疑惑

    疑惑:

    为什么在生成so文件的地方使用ldd查看依赖关系的时候,这些库是能找到的呢?如果说当前路径是默认添加到搜索路径的,我可以理解,但是,pluginmanager.so依赖于label_sensor.so和class_loader.so,但它们俩并不在当前目录下!!!

    1. 测试将make生成so文件移动位置到其他地方,看能否链接成功

    我可以将so文件移动到home/ok/下的任意位置,ldd查看都是能链接上的!

    移动到/home/ok/code/下

    移动到/home/ok/下,该文件仍然属于ok用户。

    将so文件移动到/home/下

    将so文件移动到/var下:

    移动到/opt/micros/1.0.1/lib/下:

    链接没问题,这就意味着make出来的so文件,是记录了它所依赖的其他so文件的路径信息的。

    2. 测试将make install后的so文件移动到其他地方(已经将搜索路径从/etc/ld.so.conf文件中删除)

    我们将它移动到/var目录下:

    我们把安装后的so文件复制到/home/ok/下,然后查看(用户是root):

    我们发现,将安装后的so文件移动到任何一个位置,都无法找到依赖包。

    上述两个文件的区别仅仅是文件的属主,一个是ok,一个是root。

    那么,使用make生成so文件时,依赖库的路径信息到底有么有被放到目标so中呢?如果放进去了,这个好理解,该文件可以随便移动,但是存在弊端:如果你依赖的库文件移动位置了,那就肯定找不到了。我们验证一下,把label_sensor.so从lib/plugins下移动到third-party/class_loader/lib下。(这俩路径目前都不在系统的/etc/ld.so.conf文件中)

    再挪回来:

    我们发现,labe_sensor.so虽然更换了路径,但是仍然能找到,这说明make生成so文件时,依赖库的路径并没有被放到so文件中。

    那么我们思考一下,是不是每一个用户都有一个搜索路径呢?

    如果每个用户都有一个搜索路径,那我把label_sensor.so移动到一个其他位置,是否还有效呢?

    我们将label_sensor.so移动到/opt/micros/下,然后查看:

    我们发现,找不到label_sensor.so,这也就说明(1)so文件中不记录所依赖的其他so文件的路径,只记录so文件名;(2)有可能,每个用户都有一个搜索路径,并且在执行CMakelists.txt对应的make的时候,会把link_directories和add_library添加的依赖路径添加到执行make命令的用户的搜索路径下;(3)有可能每一个so文件里面都包含了一个搜索路径,就是cmakelists.txt中的link_directories和add_library以及target_link_libraries引入的路径,当使用so或者ldd该so文件的时候,会根据so文件里面包含的路径去查找,但这样的话,即使切换用户,应该也能找到!所以这个成立的可能性很小!!!

    3. 使用sudo make来编译so文件

    生成so文件:

    然后安装该文件:

    发现不行,仍然找不到路径。

    我们使用sudo cmake ..; sudo make 再来一遍:

    sudo make install:

    仍然不行,现在我们将sudo cmake ..和sudo make得到的so文件复制到/opt/micros/1.0.1/lib/下:

    发现可以了,这说明是sudo make install破坏了原来的依赖关系!!!

    这说明前面的第二条推论也可能是错误的!!!也就是并不是在cmake ..和make的时候,会将相应的路径添加到用户的搜索路径中?但是如果这样的话,怎么解释make出来的so文件随便移动,其都能找到依赖的so文件,并且其依赖的so文件移动到某些路径下(生成目标so时的link_dictories和add_library以及target_link_libraries指定的路径下)仍然能找到呢?

    是不是生成目标so文件时,附带了对应该so的cmakelists中的link_dictories和add_library以及target_link_libraries的路径呢?也就是前面的推论(3)可能是成立的!但是sudo make install破坏了这种关系。

    我们查看以下make和make install后的文件大小的区别:

    上面的是复制过来的,下面的是安装过来的,大小一致,唯一的区别是make得到的有可执行权限。

    为什么make出来的so文件的库依赖是没有问题的,而make install出来的库文件需要添加依赖库的路径到/etc/ld.so.conf文件中呢?

    限于篇幅问题,我在下一个blog中继续探索!

    有一点需要说明,添加到/etc/ld.so.conf文件中的搜索路径必须是so文件的直接父路径,不能是祖先路径。貌似ldd不会便利某路径下的子目录。

    展开全文
  • linux 显式链接so

    2019-12-30 15:57:30
    linux加载程序变成进程的过程 fork进程, 在内核创建进程相关内核项, 加载进程可执行文件 查找依赖so库, 加载映射虚拟地址 初始化程序变量 ...查看依赖关系: readelf -d xx.so 查看链接到的so库: ...

    linux加载程序变成进程的过程
    fork进程, 在内核创建进程相关内核项, 加载进程可执行文件
    查找依赖的so库, 加载映射虚拟地址
    初始化程序变量
    动态库依赖越多, 进程启动就越慢, 并且发布程序的时候, 这些链接但没有使用的so同样要一起跟着发布, 否则进程启动时候找不到对应的so导致启动失败.

    一些查看依赖的命令
    查看依赖关系: readelf -d xx.so

    查看链接到的so库: ldd xx.so

    查看不需要链接的so库: ldd -u xx.so

    编译时自动忽略无用的so库: gcc –as-needed

    链接so库有两种途径: 显式和隐式
    显式加载: 程序主动调用dlopen打开so库, 使用dlopen打开的so并不是在进程启动时候加载映射的, 而是当进程运行到调用dlopen代码地方才加载该so; 也就是说, 如果每个进程显示链接a.so, 但是如果发布该程序时候忘记附带发布该a.so, 程序仍然能够正常启动, 甚至如果运行逻辑没有触发运行到调用dlopen函数代码地方

    显式加载的函数接口

    The four functions dlopen(), dlsym(), dlclose(), dlerror() implement the interface to the dynamic linking loader.

    void *dlopen(const char *filename, int flag);
    The function dlopen() loads the dynamic library file named by the null-terminated string filename and returns an opaque “handle” for the dynamic library.

    void *dlsym(void *handle, const char *symbol);
    The function dlsym() takes a “handle” of a dynamic library returned by dlopen() and the null-terminated symbol name, returning the address where that symbol is loaded into memory.

    int dlclose(void *handle);
    The function dlclose() decrements the reference count on the dynamic library handle handle. 
    If the reference count drops to zero and no other loaded libraries use symbols in it, then the dynamic library is unloaded.

    char *dlerror(void);
    The function dlerror() returns a human readable string describing the most recent error that occurred from dlopen(), dlsym() or dlclose() since the last call to dlerror().

    c调用示例:

    //add.h
    int add(int a, int b);
    //add.c
    #include <stdio.h>
    #include "add.h"
    int add(int a, int b)
    {
       return a+b;
    }
    //编译:gcc -shared -o add.so add.c

    //测试
    //test.c
    #include <stdio.h>
    #include <dlfcn.h>

    typedef int(*AddFunc)(int,int);

    int main()
    {
        AddFunc add;
        void* dp = NULL;

        dp = dlopen("./add.so",RTLD_LAZY );
        if(dp==NULL)
        {
            printf("dlopen failed\n");
            return 0;
        }
        add = (AddFunc)dlsym(dp,"add");
        printf("dlopen success\nresult=%d\n",add(3,4));
        dlclose(dp);

        return 0;
    }
    //编译: g++ -o main main.cpp -ldl

    备注: 如果将add改为cpp后缀, 然后编译生成so文件, test.cpp在调用dlsym函数时会出错, 原因不详! 这应该是与name mangling有关. 解决办法: 在add.h中函数声明时, 增加extern “C”防止其符号名被mangle (用 extern “C”声明的函数将使用函数名作符号名,就像C函数一样)

    c++加载类调用示例

    //BTClass.h
    #ifndef BTCLASS_H
    #define BTCLASS_H

    class BTClass
    {
    public:
        BTClass(){}
        virtual ~BTClass(){}

        virtual void Hello() = 0;
    };

    // the types of the class factories
    typedef BTClass* create_t();
    typedef void destroy_t(BTClass*);

    #endif // BTCLASS_H

    //TClass.h
    #ifndef TCLASS_H
    #define TCLASS_H

    #include "BTClass.h"
    #include <iostream>

    class TClass : public BTClass
    {
    public:
        TClass(){}
        virtual ~TClass(){}
        virtual void Hello();
    };

    // the class factories
    extern "C" BTClass* create()
    {
        return new TClass;
    }

    extern "C" void destroy(BTClass* p)
    {
        delete p;
    }

    #endif // TCLASS_H

    //TClass.cpp
    #include "TClass.h"

    void TClass::Hello()
    {
        std::cout << "this is a test for class" << std::endl;
    }

    //Test:main.cpp
    #include <iostream>
    #include <dlfcn.h>
    #include "BTClass.h"

    int main()
    {
        void* hd = dlopen("./libtclass.so",RTLD_LAZY);
        if(!hd)
            std::cerr << "Can not load lib: " << dlerror() << std::endl;

        dlerror();

        create_t* createTClass = (create_t*)dlsym(hd,"create");
        const char* dlsym_error = dlerror();
        if(dlsym_error)
        {
            std::cerr << "Can not load symbol create: " << dlsym_error << std::endl;
            return 0;
        }

        destroy_t* destroyTClass = (destroy_t*)dlsym(hd,"destroy");
        dlsym_error = dlerror();
        if(dlsym_error)
        {
            std::cerr << "Can not load symbol destroy: " << dlsym_error << std::endl;
            return 0;
        }

        BTClass* piBTClass = createTClass();
        piBTClass->Hello();

        destroyTClass(piBTClass);

        dlclose(hd);

        std::cout << "this is the end!" << std::endl;
        return 0;
    }
    extern “C”的两种声明形式

    //内联形式: 外部链接(extern linkage)和C语言链接(language linkage)
    extern "C" int foo;
    extern "C" void bar();
    //等价于花括号形式:这里只是语言链接形式
    extern "C" {
        extern int foo;
        extern void bar();
    }

    对于函数来说,extern和non-extern的函数声明没有区别,但对于变量就有不同了

    extern "C" int foo;//是个声明
    extern "C" {//不仅是声明,也可以是定义
        int foo;
    }
    编译使用-fPIC的作用(Position Independent Code)

    不加-fPIC生成的so, 必须要在加载到用户程序的地址空间时, 重定向所有表目
    加上-fPIC生成的so, 与位置无关; 这样的代码本身就能被放到线性地址空间的任意位置,无需修改就能正确执行。通常的方法是获取指令指针的值,加上一个偏移得到全局变量/函数的地址
    加上-fPIC生成的so, 可以实现多个进程共享
    参考链接

    折腾gcc/g++链接时.o文件及库的顺序问题
    linux下so动态库一些不为人知的秘密
    Linux共享对象之编译参数fPIC
    dlopen加载c++ 函数及类
     

    展开全文
  • linux查看文件依赖的库

    千次阅读 2014-02-13 18:44:38
    一般使用ldd命令查看文件依赖的库(.so) ldd file 工具还提供了另外2个命令可以使用 xx-linux-readelf -a "your binary" | grep "Shared" xx-linux-objdump -x "your binary" | grep "NEEDED" 曲线方式 ...

    一般使用ldd命令查看文件所依赖的库(.so)
    ldd file

    工具链还提供了另外2个命令可以使用
    xx-linux-readelf -a "your binary" | grep "Shared"

    xx-linux-objdump -x "your binary" | grep "NEEDED"

    曲线方式
    启动可执行文件,获取其pid
    cat /proc/pid/maps获取其所依赖的所有so

    展开全文
  • 可以通过ldd命名来查看可执行文件依赖的动态链接库,如下(其中D为可执行程序): 其中的libjson_linux-gcc-4.6_libmt.so cannot found。解决这个问题: (1)在系统中查找这个文件(当然要保证系统中已经有这个.so文件...

    如果使用自己手动生成的动态链接库.so文件,但是这个.so文件,没有加入库文件搜索路劲中,程序运行时可能会出现找不到动态链接库的情形。

    可以通过ldd命名来查看可执行文件依赖的动态链接库,如下(其中D为可执行程序):

     其中的libjson_linux-gcc-4.6_libmt.so cannot found。

    解决这个问题:

     (1)在系统中查找这个文件(当然要保证系统中已经有这个.so文件,只是查找路径没有设置正确而已):

      sudo find / -name libjson_linux-gcc-4.6_libmt.so

      结果:/home/liu/Desktop/jsoncpp-src-0.5.0/libs/linux-gcc-4.6/libjson_linux-gcc-4.6_libmt.so

    (2)将.so文件路径的目录添加到/etc/ld.so.conf

       sudo vim /etc/ld.so.conf

      文件末尾新添加一行,/home/liu/Desktop/jsoncpp-src-0.5.0/libs/linux-gcc-4.6

    (3)使得修改生效

      sudo /sbin/ldconfig

     

    这样就不会有那个找不对.so文件的错误啦。

    参考:http://www.blogjava.net/zhyiwww/archive/2007/12/14/167827.html

    展开全文
  • Linux下静态库_库的基本概念;...nm查看库中包含那些函数、ar生成静态库,查看库中包含那些.o文件、ldd查看程序依赖的.so文件;gcc/g++与库相关的参数-L,-l,-fPIC,-shared;静态库链接时搜索过程;
  • linux strip 可以去除链接信息 让nm看不到 但是readelf 用-s参数 仍然可以看到 例如readelf -s libACE-...查看共享库的依赖库(NEEDED)和搜索名(SONAME)。 readelf -d 例如: #readelf -d libuClibc-0.9.30r
  • linux 添加第三方库 .so

    千次阅读 2013-01-04 09:57:32
    1.拷贝第三方库.so 到相应的linux文件夹。注意 不是链接文件 2.链接相应的.so 至指定的.so 名称 ldd 查看依赖关系 ldd xxxx.so
  • 调试ffmpeg+sdl的时候,新安装了sdl2库,运行我的执行程序时报找不到sdl2.so的引用。我查看了sdl2.so明明装在了/etc...1、linux下使用ldd命令可以查看你的执行程序依赖的共享库,以及该共享库在你的linux文件系统中的位
  • Linux下的库文件

    2013-11-05 15:27:27
    Linux下有两种库文件: 1、静态库---- xxx.a 2、动态库---- xxx.so   //TODO 动态库,静态库区别: 1、链接方式:  静态库在编译的时候会链接到程序。  动态库在加载时指定程序的跳转位置。---有点忘了,...
  • linux动态库和静态库

    2015-12-27 20:22:06
    Linux下静态库_库的基本概念;如何生成静态库动态库;nm查看库中包含那些函数、ar生成静态库,查看库中包含那些.o文件、ldd查看程序依赖的.so文件;gcc/g++与库相关的参数-L,-l,-fPIC,-shared;静态库链接时
  • 0x01 .interp内容是一个字符串,保存了动态链接器的路径,如/lib/ld-linux.so.2 有几种查看方式: objdump -s a.out readelf -l a.out | grep interpreter0x02 .dynamic保存了动态链接器所需的基本信息,具体...
  • 动态链接与静态链接

    2019-11-18 17:42:20
    动态是指在应用程序运行时才去加载外部的代码库,例如 printf 函数的 C 标准代码库*.so 文件存储在 Linux 系统的某个位置,hello 程序执行时调用库文件*.so 中的内容,不同的程序可以共用代码库。所以动态链接生成的...
  • 1.Linux可执行程序1.1静态链接静态可执行程序包含所需的所有函数,换句话说,它们是“完整的”,因为这一原因,静态可执行程序不依赖任何外部库就可以运行1.2动态链接动态可执行程序是不完整的程序,它依靠外部共享...
  • nm查看库中包含那些函数、ar生成静态库,查看库中包含那些.o文件、ldd查看程序依赖的.so文件;gcc/g++与库相关的参数-L,-l,-fPIC,-shared;静态库链接时搜索过程;动态库链接时,加载时搜索的过程;动态库找不到的问题;库...
  • 通过 ldd -rxxx.so命令查看so库链接状态和错误信息 ldd命令,可以查看对应的可执行文件或库文件依赖哪些库,但可执行文件或库文件要求与操作系统的编译器类型相同,即电脑是X86的GCC编译器,那么无法通过ldd命令...
  • ldd:查看当前程序依赖的动态库文件 C动态库:lib.so.6 => /usr/lib64.so.6 file:可以查看当前文件属性   2.动态库 生成 gcc/g++ -shared -fPIC test.c -o(后面生成的动态库的名字) 前缀:lib 后缀:....
  • 若生成Windows中的qjson类库,也可以使用Qt Creator打开里面的qjson.pro文件,然后构建,不过生成的不是.a文件或.so文件,而是.lib或.dll文件,而且也不需要配置连接程序ld。估计只需要配置下vs或其他IDE的...
  • Linux入门基础操作(ubuntu20.04)(八) 动态库的创建与使用: 1)命名规则 lib+name+.so 2)制作步骤 gcc -fPIC -c xxx.c:生成与位置无关的代码(生成与...ldd +可执行程序:查看依赖共享库的名字 解决办法: 1)临
  • 编译通过了,我查看了下生成的可执行文件zmq_version 所依赖的共享库文件列表: $ ldd zmq_version  linux-vdso.so.1 => (0x00007ffd2c9f3000)  libzmq.so.5 => /usr/local/zeromq/lib/libzmq.so.5 (0x00007...
  • 查看的方法是使用ldd lmstart找出该文件所需要的依赖库 然后使用locate查看该库是否存在系统 如果不存在则在对应的位置创建链接 在/lib/x86_64-linux-gnu/目录执行链接 ln -s /lib/x86_64-linux-gnu/libpthread.so...
  • 2014-11-18 18:45:39
    Linux下静态库_库的基本概念;如何生成静态库动态库;nm查看库中包含那些函数、ar生成静态库,查看库中包含那些.o文件、ldd查看程序依赖的.so文件;gcc/g++与库相关的参数-L,-l,-fPIC,-shared;静态库链接时
  • 静态库/动态库

    2014-07-11 09:43:51
    nm查看库中包含那些函数、ar生成静态库,查看库中包含那些.o文件、ldd查看程序依赖的.so文件;gcc/g++与库相关的参数-L,-l,-fPIC,-shared;静态库链接时搜索过程;动态库链接时,加载时搜索的过程;动态库找不到的问题;库...
  • 在ubuntu上可以用用 ldd 查看一个文件的动态链接库依赖。这样就看可以一目了然,需要给哪些东西了。 例子 这里以我自己编译的一个 exe 为例: ldd segDemo out: linux-vdso.so.1 (0x00007ffd14b29000) ...
  • 可以将Javascript源编译为没有外部依赖的可执行文件。 使用引用计数(以减少内存使用并具有确定性行为)的垃圾收集与循环删除。 数学扩展:BigInt, BigFloat, 运算符重载, bigint模式, math模式. 在Javascript中实现...
  • 11.我们双击文件列表的dialog.ui 文件,便出现了下面所示的图形界面编辑界 面。 12.我们在右边的器件栏里找到Label 标签器件 13.按着鼠标左键将其拖到设计窗口上,如下图。 14.我们双击它,并将其内容改为helloworld...
  • 下载并解压后,将解压出的整个文件夹复制或者移动到your sdk 路径/sources文件夹下,然后重启Eclipse(或Android Studio),这样当你在Eclipse里面按住Ctrl键点击某个系统类时就可以打开该类的源码文件查看源码了。...
  • 下载完成后,把16b版本toolchains\mips64el-linux-android-4.9\prebuilt\windows-x86_64的所有文件copy到r17中toolchains\mips64el-linux-android-4.9\prebuilt\windows-x86_64目录下也可以解决 Invoke-customs ...

空空如也

空空如也

1 2
收藏数 34
精华内容 13
关键字:

linux依赖链查看so文件

linux 订阅