在用SourceInsight分析VLC-Android源码过程中,有几个宏定义在源代码中一直没有找到出处,比如 HAVE_DYNAMIC_PLUGINS和__PLUGIN__,以及MODULE_NAME和MODULE_STRING,在网上找了VLC源码的分 析资料都是老版本的,老版本中MODULE_NAME在每一个MODULES模块下面都有定义,MODULE_STRING也有如下宏定义:

[cpp] view plaincopy

 
  1. #define STRINGIFY(z)   UGLY_KLUDGE(z)
  2. #define UGLY_KLUDGE(z)  #z
  3. #define MODULE_STRING  STRINGIFY(MODULE_NAME)

但是在新版本的VLC源码中,MODULE_NAME除了在vlc/src/libvlc-modules.c文件中有#define MODULE_NAME main 的定义外,其他再无出处,MODULE_STRING更是没有找到任何定义,后来发现实际上GCC在编译时可以向源文件中传递宏定义,形式如gcc -Dmacro 或者 gcc -Dmacro=defn,于是去看查看makefile文件,果然在modules/common.am文件中有如下发现

[cpp] view plaincopy

 
  1. # Module name from object or executable file name.
  2. MODULE_NAME = $$(p="$@"; p="$${p\#\#*/}"; p="$${p\#lib}"; echo "$${p%_plugin*}")
  3. AM_CPPFLAGS = \
  4. -DMODULE_NAME=$(MODULE_NAME) \
  5. -DMODULE_NAME_IS_$(MODULE_NAME) \
  6. -DMODULE_STRING=\"$(MODULE_NAME)\"
  7. if HAVE_DYNAMIC_PLUGINS
  8. AM_CPPFLAGS += -D__PLUGIN__
  9. endif

实际上问题已经逐渐明朗,就是在编译过程中gcc向源文件传递了宏定义,为了查看编译选项,分别对VLC-Android和VLC的vlc/modules/demux/live555.cpp的的编译选项进行了输出,这里做的办法是对vlc/modules/demux/makefile.in文件进行了修改,找到编译目标

[cpp] view plaincopy

 
  1. liblive555_plugin_la-live555.lo: live555.cpp

在其下面添加如下代码

[cpp] view
plain
copy

 
  1. @am__fastdepCXX_TRUE@   echo $(AM_V_CXX) $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblive555_plugin_la_CPPFLAGS) $(CPPFLAGS)
  2. $(liblive555_plugin_la_CXXFLAGS) $(CXXFLAGS)  -E -o testlive555.txt live555.cpp

并在编译前用script
-a test.txt命令进行终端输出记录,得到如下结果

VLC-Android输出如下:

[cpp] view
plain
copy

 
  1. echo @echo "  CXX   " liblive555_plugin_la-live555.lo;
  2. /androidApp/android-ndk-r8b/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/bin//arm-linux-androideabi-g++
  3. --sysroot=/androidApp/android-ndk-r8b/platforms/android-9/arch-arm -DHAVE_CONFIG_H -I. -I../../../modules/demux -I../..
  4. -DMODULE_NAME=$(p="liblive555_plugin_la-live555.lo"; p="${p##*/}"; p="${p#lib}"; echo "${p%_plugin*}")
  5. -DMODULE_NAME_IS_$(p="liblive555_plugin_la-live555.lo"; p="${p##*/}"; p="${p#lib}"; echo "${p%_plugin*}")
  6. -DMODULE_STRING=\"$(p="liblive555_plugin_la-live555.lo"; p="${p##*/}"; p="${p#lib}"; echo "${p%_plugin*}")\"
  7. -I../../../include -I../../include -I/androidApp/android-ndk-r8b/sources/cxx-stl/gnu-libstdc++/4.6/include
  8. -I/androidApp/android-ndk-r8b/sources/cxx-stl/gnu-libstdc++/4.6/libs/armeabi-v7a/include
  9. -I/vlc-android/android/vlc/contrib/arm-linux-androideabi/include
  10. -I/vlc-android/android/vlc/contrib/arm-linux-androideabi/include/liveMedia
  11. -I/vlc-android/android/vlc/contrib/arm-linux-androideabi/include/groupsock
  12. -I/vlc-android/android/vlc/contrib/arm-linux-androideabi/include/BasicUsageEnvironment
  13. -I/vlc-android/android/vlc/contrib/arm-linux-androideabi/include/UsageEnvironment -g -O2
  14. -fstrict-aliasing -funsafe-math-optimizations -mlong-calls
  15. -I/vlc-android/android/vlc/contrib/arm-linux-androideabi/include -Wall -Wextra -Wsign-compare
  16. -Wundef -Wpointer-arith -Wvolatile-register-var -fvisibility=hidden -ffast-math -funroll-loops
  17. @echo   CXX    liblive555_plugin_la-live555.lo

VLC输出如下:

[cpp] view
plain
copy

 
  1. echo @echo "  CXX   " liblive555_plugin_la-live555.lo;
  2. g++ -DHAVE_CONFIG_H -I. -I../..
  3. -DMODULE_NAME=$(p="liblive555_plugin_la-live555.lo"; p="${p##*/}"; p="${p#lib}"; echo "${p%_plugin*}")
  4. -DMODULE_NAME_IS_$(p="liblive555_plugin_la-live555.lo"; p="${p##*/}"; p="${p#lib}"; echo "${p%_plugin*}")
  5. -DMODULE_STRING=\"$(p="liblive555_plugin_la-live555.lo"; p="${p##*/}"; p="${p#lib}"; echo "${p%_plugin*}")\"
  6. -D__PLUGIN__
  7. -I../../include -I../../include
  8. -I/home/vlc/contrib/i486-linux-gnu/include
  9. -I/home/vlc/contrib/i486-linux-gnu/include/liveMedia
  10. -I/home/vlc/contrib/i486-linux-gnu/include/groupsock
  11. -I/home/vlc/contrib/i486-linux-gnu/include/BasicUsageEnvironment
  12. -I/home/vlc/contrib/i486-linux-gnu/include/UsageEnvironment -g -O2
  13. -I/home/vlc/contrib/i486-linux-gnu/include -Wall -Wextra -Wsign-compare -Wundef -Wpointer-arith
  14. -Wvolatile-register-var -fvisibility=hidden -ffast-math -funroll-loops -fomit-frame-pointer
  15. @echo   CXX    liblive555_plugin_la-live555.lo

从上面的输出可以看出,gcc的确添加了MODULE_NAME,MODULE_NAME_IS_,MODULE_STRING的宏定义,但是两个还略有
不同,即VLC还添加了__PLUGIN__的宏定义,而VLC-Android没有,这就是VLC-Android和VLC的根本的不同,VLC-
Android的各个模块实际上是静态加载的,而VLC的各个模块默认是动态加载的,对于动态加载如网上的很多资料所说,除了main模块调用的实际函数
为导出函数vlc_entry_main,其他模块导出的均为vlc_entry__2_1_0a(本文VLC版本为2.0.4)。而对于静态加载,每一
个模块都有它自己的导出函数,为了验证,同样对live555.cpp文件进行预编译处理,即gcc
-E,如上面代码在makefile.in中的配置,注意去掉echo。我们查看两个工程的输出文档testlive555.txt,可以发现如下:

VLC-Android中的该文件内容为:

[cpp] view
plain
copy

 
  1. extern "C" int vlc_entry__live555 (vlc_set_cb, void *);
  2. extern "C" int vlc_entry__live555 (vlc_set_cb vlc_set, void *opaque)
  3. {
  4. module_t *module;
  5. module_config_t *config = __null;
  6. if (vlc_set (opaque, __null, VLC_MODULE_CREATE, &module)) goto error;
  7. if (vlc_set (opaque, module, VLC_MODULE_NAME, ("live555"))) goto error;
  8. ...

而VLC中的该文件内容为:

[cpp] view
plain
copy

 
  1. extern "C" __attribute__((visibility("default"))) int vlc_entry__2_1_0a (vlc_set_cb, void *);
  2. extern "C" __attribute__((visibility("default"))) int vlc_entry__2_1_0a (vlc_set_cb vlc_set, void *opaque)
  3. {
  4. module_t *module;
  5. module_config_t *config = __null;
  6. if (vlc_set (opaque, __null, VLC_MODULE_CREATE, &module)) goto error;
  7. if (vlc_set (opaque, module, VLC_MODULE_NAME, ("live555"))) goto error;
  8. ...

说明分析结果为真,实际上代码中也已经有了说明,我们查看vlc/include/vlc_plugin.h中有如下定义

[cpp] view
plain
copy

 
  1. # define MODULE_SYMBOL 2_1_0a
  2. # define MODULE_SUFFIX "__2_1_0a"
  3. #define CONCATENATE( y, z ) CRUDE_HACK( y, z )
  4. #define CRUDE_HACK( y, z )  y##__##z
  5. #ifdef __PLUGIN__
  6. #   define __VLC_SYMBOL( symbol  ) CONCATENATE( symbol, MODULE_SYMBOL )
  7. #else
  8. #   define __VLC_SYMBOL( symbol )  CONCATENATE( symbol, MODULE_NAME )
  9. #endif

即定义了__PLUGIN__,那么就用MODULE_SYMBOL,否则就用MODULE_NAME,那么__PLUGIN__又在哪里定义了呢?为什么VLC-Android和VLC又不同呢,我们回到上面的源头,发现

[cpp] view
plain
copy

 
  1. if HAVE_DYNAMIC_PLUGINS
  2. AM_CPPFLAGS += -D__PLUGIN__
  3. endif

那么这个HAVE_DYNAMIC_PLUGINS又从哪里来呢?这实际上就是VLC-Android和VLC两者的不同,一个有宏定义__PLUGIN__,一个没有宏定义__PLUGIN__。

而实际上HAVE_DYNAMIC_PLUGINS是在运行configure过程中对其进行配置的。

我们在vlc/configure.ac中发现有如下代码:

[cpp] view
plain
copy

 
  1. dnl Check for dynamic plugins
  2. LIBDL=""
  3. have_dynamic_objects="no"
  4. VLC_SAVE_FLAGS
  5. AC_SEARCH_LIBS(dlopen, [dl svld], [
  6. AS_IF([test "$ac_cv_search_dlopen" != "none required"], [
  7. LIBDL="$ac_cv_search_dlopen"
  8. ])
  9. have_dynamic_objects="yes"
  10. ])
  11. VLC_RESTORE_FLAGS
  12. # Windows
  13. AS_IF([test "${SYS}" = "mingw32"], [
  14. LIBDL=""
  15. have_dynamic_objects="yes" #assume we can use shared objects
  16. ])
  17. AS_IF([test "${enable_shared}" = "no"], [
  18. have_dynamic_objects=no
  19. ])
  20. AM_CONDITIONAL(HAVE_DYNAMIC_PLUGINS, [test "${have_dynamic_objects}" != "no"])

这就是问题的源头所在了,即在运行configure时是否配置了--enable-shared来决定HAVE_DYNAMIC_PLUGINS为
true还是false,因此我们再去查看运行configure时的配置,在VLC-Android的android目录下的configure.sh
文件中,我们发现了如下代码:

[cpp] view
plain
copy

 
  1. sh $VLC_SOURCEDIR/configure --host=$TARGET_TUPLE --build=x86_64-unknown-linux $EXTRA_PARAMS \
  2. --enable-live555 --enable-realrtsp \
  3. --enable-avformat \
  4. --enable-swscale \
  5. --enable-avcodec \
  6. --enable-opus \
  7. --enable-opensles \
  8. --enable-android-surface \
  9. --enable-mkv \
  10. --enable-taglib \
  11. --enable-dvbpsi \
  12. --disable-vlc --disable-shared \

问题实际上已经浮出水面,这里配置了--disable-shared,而在VLC中我们一般保持默认配置,为此我们再运行vlc目录下的configure
--help来查看默认配置选项,在输出的文档中我们发现了如下描诉:

[cpp] view
plain
copy

 
  1. --enable-shared[=PKGS]  build shared libraries [default=yes]
  2. --enable-static[=PKGS]  build static libraries [default=no]
  3. --with-pic              try to use only PIC/non-PIC objects [default=use
  4. both]
  5. --enable-fast-install[=PKGS]
  6. optimize for fast installation [default=yes]

即默认配置为--enable-shared,再结合前面的代码,就可以知道VLC-Android中的HAVE_DYNAMIC_PLUGINS值为
FALSE,而VLC中的HAVE_DYNAMIC_PLUGINS值为TRUE,从而添加了__PLUGIN__的宏定义。以此为源头从而影响了
VLC-Android和VLC后面的一系列不同的代码。

VLC-Android和VLC几个关键宏定义的分析的更多相关文章

  1. android的 makefile里 的常用 宏定义

    在Android编译框架中,把许多固定的.反复用到的目录路径定义为 宏变量,常用 宏 如下: out/target/product/xxx的宏即为:PRODUCT_OUT out/target/pro ...

  2. android C/C++ source files 全局宏定义 .

    \system\core\include\arch\linux-arm AndroidConfig.h * ============================================== ...

  3. Ubuntu15.10 编译VLC Android(安卓)过程记录

    持续更新中... 最后一次修改于 2016-03-20 15:33:45 1.必要库的安装 除基本编译环境(gcc.g++等外),需要额外安装如下的库(用于下载必要的依赖文件) (1)JDK 推荐安装 ...

  4. 【转】vlc android 代码编译

    转自:http://blog.csdn.net/asircao/article/details/7734201 系统:ubuntu12.04代码:git://git.videolan.org/vlc- ...

  5. Android.mk宏定义demo【转】

    本文转载自:http://blog.csdn.net/u010164190/article/details/72783963 1.Android.mk  LOCAL_PATH := $(call my ...

  6. Android应用程序键盘(Keyboard)消息处理机制分析

    在Android系统中,键盘按键事件是由WindowManagerService服务来管理的,然后再以消息的形 式来分发给应用程序处理,不过和普通消息不一样,它是由硬件中断触发的:在上一篇文章< ...

  7. dll导入导出宏定义,出现“不允许 dllimport 函数 的定义”的问题分析

    建立dll项目后,在头文件中,定义API宏 #ifndef API_S_H #define API_S_H ...... #ifndef DLL_S_20160424 #define API _dec ...

  8. 黑马程序员——C语言基础 枚举 宏定义 自定义 static exterm

    Java培训.Android培训.iOS培训..Net培训.期待与您交流! (以下内容是对黑马苹果入学视频的个人知识点总结) (一)枚举 1)枚举类型的定义 枚举是C语言中的一种基本数据类型,并不是构 ...

  9. VC中预处理指令与宏定义详解

    刚接触到MFC编程的人往往会被MFC 向导生成的各种宏定义和预处理指令所吓倒,但是预处理和宏定义又是C语言的一个强大工具.使用它们可以进行简单的源代码控制,版本控制,预警或者完成一些特殊的功能. 一个 ...

随机推荐

  1. Android应用程序的Activity启动过程简要介绍和学习计划

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6685853 在Android系统中,Activ ...

  2. NET中级课--文件,流,序列化2

    1.流的类型体系: 基础流    装饰器流    包装器类    帮助类 2.               stream file~     memory~     network~ stream是个 ...

  3. 前端--关于客户端javascript

    浏览器中的Javascript 客户端javascript就是运行在浏览器中的javascript,现代的浏览器已经有了很好的发展,虽然它是一个应用程序,但完全可以把它看作是一个简易的操作系统,因为像 ...

  4. VS 2003 无法打开Web项目 文件路径与URL不符 这两者需要映射到相同的服务器位置

    解决方法: 将C:\Documents   and   Settings\Administrator\VSWebCache下面的文件全部删除

  5. @synthesize

    @synthesize 相当于把属性当成成员变量来用,不用再写self.属性@synthesize myButton; 这样写了之后,那么编译器会自动生成myButton的实例变量,以及相应的gett ...

  6. gradle构建依赖

    本地依赖 gradle 作为构建工具,能够很方便的使用本地jar包,以下为使用的代码块. dependencies { //单文件依赖 compile files('libs/android-supp ...

  7. css:hover选择器

    :hover 选择器用于选择鼠标指针浮动上面的元素. :hover选择器可以用于所有的元素,不单是链接. 提示::link选择器设置指向未被访问页面的链接的样式,:visited选择器用于设置指向已被 ...

  8. maven使用笔记一 下载json-lib引发的问题

    一.问题描述(IDEA中): 1,在pom.xml中配置了 <dependency> <groupId>net.sf.json-lib</groupId> < ...

  9. Oracle中MERGE语句的使用

    Oracle在9i引入了merge命令, 通过这个merge你能够在一个SQL语句中对一个表同时执行inserts和updates操作. 当然是update还是insert是依据于你的指定的条件判断的 ...

  10. ThreadLocal的使用 .

    早在Java 1.2推出之时,Java平台中就引入了一个新的支持:java.lang.ThreadLocal,给我们在编写多线程程序时提供了一种新的选择.使用这个工具类可以很简洁地编写出优美的多线程程 ...