关于动态库之间stl调用的问题

最近在做cocos2dx的自更新,因为一开始没有选择用lua,所以现在不得不找其他出路来做自更新。

当然直接的想法就是把逻辑丢到一个动态库里面,框架部分加一个资源管理ok。然后问题就来了

一开始在4.4的android设备上测试,一切正常,但是拿到4.0.4的机器上就直接崩溃了,anrdoid调试起来很困难,弄了很久也没搞定,放弃。

第一个症状,初始化LabelAtlas时挂掉,挂的很尴尬,看不出理由的(至少当时是这样),看着好像内存被写乱了,但是怎么也查不到。

然后瞎折腾了半天,居然找到了一个解决方法。因为是在LabelAtlas写本地字符缓冲m_sString时导致的崩溃,弄了很多方法,最后在UICCLabelAtlas加了一个函数修改m_sString,在setProperty之前调用这个函数先写入传来的字符串。崩溃没了(原因至今不明)。

然后继续玩下

二号问题来了。登陆部分做了账号密码缓存,这个东西用到了CCUserDefault,实际上这个东西在win32下跟android上的实现完全不同。结果是,如果玩家第一次进入,也就是没有账号密码缓存的时候,返回的数据一旦被操作就会导致内存错误,产生段错误而崩溃。这个问题也仅存在于4.0.4的设备上(其他低版本设备没测试过)。

最后说重点,问题产生的原因,与解决方法。

原因是就是标题说的,stl对象跨动态库传递导致。stl全都是基于模板的,模板是在编译器生成的。这也就是说同一份stl代码在不同动态库中有各自的实现,如果只是方法多了一份自然就没问题,但是部分stl容器里面存有一些静态变量,因此多个实现会导致多份静态变量,然后导致某些方法的调用出现差别,最终导致内存操作异常而崩溃(这个原因是网上查的,这些是我大概的理解原链接)。

LabelAtlas里面有一个UICCLabelAtlas对象。而UICCLabelAtlas继承自CCAtlasNode,CCAtlasNode则是cocos2dx库中的东西,cocos2dx被我编译成了一个独立的so文件,LabelAtlas则在libextension.so中。m_sString成员变量是在CCAtlasNode中定义的,因此UICCLabelAtlas的存在导致了m_sString被两个so中的stl实现所操作,然后崩溃。

CCUserDefault是cocos2dx的实现,我的逻辑代码则在逻辑动态库中,而取值函数getStringForKey的返回参数则是一个std::string,同样造成了一个对象被两套方法处理导致混乱崩溃。

PS:cocos2dx版本2.2.2,这种问题在win32,android4.2+,ios模拟器7.0+都没有出现过,另外第一个问题的奇怪解法也让我看不懂,有知情者请留言交流

时间: 2024-10-04 00:59:55

关于动态库之间stl调用的问题的相关文章

linux主文件和动态库之间变量和函数访问

通常我们需要从动态库里面直接调用可执行程序中的函数和变量,如果调用了-l选项,linux进程会自动把动态库的函数和变量加入到动态段中,所以直接访问是没有问题的. 我们这里要说的是非显示连接动态库,而是直接从c文件中通过dlopen函数打开动态库访问的方式,此时,gcc编译器不知道SO需要调用哪一个函数,所以不会讲函数放到动态段.故查找函数或者变量的时候,会出现找不到可执行程序中的符号的情况. 为什么会出现需要在c文件中直接dlopen动态库的情况呢? 这种情况一般出现在又不想重启进行,又需要有功

Live555 中的客户端动态库.so的调用方式之一 程序中调用

1.  打开动态链接库:    #include <dlfcn.h>    void *dlopen(const char *filename, int flag);    该函数返回操作句柄,如:    void *pHandle = dlopen(strSoFilePath, RTLD_LAZY); 2.  取动态对象地址:    #include <dlfcn.h>    void *dlsym(void *pHandle, char *symbol);    dlsym根据

Linux链接库三(C跟C++之间动态库的相互调用)

http://www.cppblog.com/wolf/articles/74928.html http://www.cppblog.com/wolf/articles/77828.html http://www.jb51.net/article/34990.htm C和C++之间库的互相调用 extern "C"的理解:很多人认为"C"表示的C语言,实际并非如此,"C"表示的是一种链接约定,只是因C和C++语言之间的密切关系而在它们之间更多的应

运行时库以及静态库,动态库之间的关系

了解篇 http://www.cnblogs.com/renyuan/p/5031100.html 知道MT,MD之间的不同,MT会将LIBC.LIB或者LIBCMT.LIB打包进可执行程序, 而MD则告诉可执行程序,运行的时候调用msvcrt.dll,因此任何一个工程 只能选择运行时库中的一种方式,MD,MDd,MT,MTd,这四种方式的一种, 连接C库,不管是一个静态库,还是一个动态库,还是一个可执行程序, 链接的其他库的时候,都必须保持一致,否则就会出现如下的提示: 错误 LNK2038

VS之动态库实现和调用

程序开发中,经常会使用到动态库,那么动态库该如何实现和调用呢?本文通过一个简单的例子实现. 使用工具:VS2008 使用语言:C++ 开发步骤: 1.新建动态库程序 1.1新建调用类和类中函数的动态库 新建类,在.h和.cpp文件顶部分别添加定义,并在类名前加上导出标志 DllFunc.h #pragma once #ifdef MY_DLL_EXPORTS #define MY_DLL_API __declspec(dllexport) #else #define MY_DLL_API __d

c++动态库封装及调用(1、动态库介绍)

1.一个程序从源文件编译生成可执行文件的步骤: 预编译 -->  编译 -->  汇编 --> 链接 (1)预编译,即预处理,主要处理在源代码文件中以"#"开始的预编译指令,如宏展开.处理条件编译指令.处理#include指令等. (2)编译过程就是把预处理完的文件进行一系列词法分析.语法分析.语义分析以及优化后生成相应的汇编代码文件. (3)汇编是将汇编代码转变成二进制文件. (4)链接将二进制文件链接成一个可执行的命令,主要是把分散的数据和代码收集并合成一个单一的

Android底层笔记:APP通过JNI调用动态库.so

开发环境: 平板电脑:FSPAD-733,原理上来说任何支持安卓的开发板都可以: eclipse:使用的是iTOP-4412开发板提供的eclipse安卓开发包: Ubuntu:使用的是FSPAD-733虚拟机开发环境,原理上来说任何开发包提供的虚拟机环境都是可以的. 加载库名,然后系统自动到库目录下找.so动态库 目录/库文件名 loadLibrary ? ? ? du -mh tags androidL/art/ vi -t Runtim_nativeLoad ? ? ? javah -jn

Android WebView加载Chromium动态库的过程分析

Chromium动态库的体积比较大,有27M左右,其中程序段和数据段分别占据25.65M和1.35M.如果按照通常方式加载Chromium动态库,那么当有N个正在运行的App使用WebView时,系统需要为Chromium动态库分配的内存为(25.65 + N x 1.35)M.这是非常可观的.为此,Android使用了特殊的方式加载Chromium动态库.本文接下来就详细分析这种特殊的加载方式. 老罗的新浪微博:http://weibo.com/shengyangluo,欢迎关注! 为什么当有

linux 动态库插件技术(c/c++):动态链接库

概述 插件技术的目的是为了更好的扩展性.动态链接库是其中 一种实现方式. 这里主要论述几个问题. 1)linux上关于这些api的描述.看完linux上关于dlopen等函数的描述基本就可以写出简单的动态链接库使用. 2)关于c++使用动态链接库的一些问题和注意事项. 3)扩展,编译器的各选项,动态链接库和静态链接库. linux api:dlopen,dlsym,dlerror,dlclose 摘自ubuntu kylin 14.04,内核3.13.0-32generic #include<d