1
jukka 2015-07-26 17:23:30 +08:00
show me your code.
|
2
XiXiLocked 2015-07-26 17:26:01 +08:00 1
你看直接读navMesh是有值的,但是指针转换之后读的navMesh是NULL,说明转的有问题
信口开河一把, scene的内存布局是 scene::vptr scene::members ... MainGameScene的里面有并不继承于scene的虚函数,所以他的虚表插在了前面,于是布局大概是这样 scene:vptr MainGameScene::vptr <--这里多了虚表指针的8 scene::members ... MainGameScene::members ... 上面说的没有把握,但是你可以看看之前的成员变量的地址验证一下 |
4
acros OP @XiXiLocked
_navMesh应该是空的。mGaneLayer不是null |
5
acros OP @XiXiLocked 我去验证下..
|
6
finab 2015-07-26 17:56:03 +08:00
代码出问题
我从不怀疑编译器或IDE,肯定是我的问题! 就是这么自信 ~~~ |
7
fo2w 2015-07-26 18:04:52 +08:00
虽然说vs确实有bug, 但我不相信大多数人碰得到
|
8
Athrob 2015-07-26 18:07:04 +08:00
确定不是代码的问题?我相信vs
|
9
nozama 2015-07-26 18:56:03 +08:00 via Android
vs2012 bug像这种“明明是对的,结果就是不对”倒是遇到过几次,在2013和appcode都没问题。也有几次,是变量忘了初始化引起的bug,clang会自动初始化为0,VC却是随机值。
|
10
lcsky 2015-07-26 19:05:38 +08:00 1
可能是遗漏了某些概念,我随便拍拍脑袋能想到相关的可能有:
1、struct、class成员的默认内存对齐方式(#pragma pack) 2、不清楚C++其实是没有ABI兼容性的 后面这个问题会导致不同的C++编译器、编译器版本、甚至只是不同的编译参数生成的二进制代码不兼容。你看系统库都是纯C接口的发现没有?因为纯C有函数调用的ABI兼容性标准:stdcall、cdecl、fastcall。而C++是彻底没有ABI兼容性的,能“差不多对上”只是运气好,或者编译器版本、参数完全一样。 所以重点恐怕是检查你dll和主程序的编译参数有何区别 |
11
acros OP |
12
husinhu 2015-07-26 20:59:46 +08:00 1
同意@lcksy 如果真是ABI不同或者编译选项不同,建议同一编译选项,加一层SceneAdaptor来decouple
|
13
lingo233 2015-07-26 21:06:32 +08:00
我受不了了明明2015已经发布了竟然不升级,要被逼疯了(╯-_-)╯╧╧
|
14
nozama 2015-07-26 21:29:20 +08:00 1
也许还有一种可能, 也是vs2012的bug: 某个源文件会莫名其妙被copy一份, 然后无论怎么修改, 编译的仍是原来的那个文件.
于是就可能出现: 头文件更新了, dll其实还是以前的, 然后按照偏移量访问某个字段, 实际上是访问到了另一个字段. |
15
endrollex 2015-07-26 22:09:46 +08:00 1
http://blog.csdn.net/smstong/article/details/24455371
如果C++编译器不能根据类声明推算出类型转换时的指针调整方式时,如果使用了强制类型转换,那么编译器只是简单的默默无作为 |
16
bombless 2015-07-26 23:18:23 +08:00 1
以前见到有个人有类似的问题,貌似是同一个变量名在不同的命名空间用上了,然后链接的时候出错(或者是调试器显示的有问题,忘记具体情况了)
|
17
mljack 2015-07-26 23:25:22 +08:00 1
检查下dll和主程序的工程设置中预编译宏是否一致,感觉像 #ifdef xxx 造成的问题,c/c++编译器对于一些.h 和.lib里的class是否一致并不做完整的检查。
仔细看了一下,应该是编译 dll 时没定义CC_USE_NAVMESH,而使用 dll 时又定义了CC_USE_NAVMESH造成的。 |
18
tushiner 2015-07-26 23:29:28 +08:00
我开发的时候也是用网易云音乐听歌
|
19
acros OP @mljack 这个我确认过了。如果CC_USE_NAVMESH关闭掉,读取错误的地址还是偏移8(这时候就是_navMesh前面的变量读取错误了),应该不是具体变量造成的。
|
20
xdeng 2015-07-26 23:31:09 +08:00 1
有个东西 叫 字节对齐
|
21
mljack 2015-07-27 00:06:22 +08:00 1
在主程序和dll中分别把 每个scene成员的偏移都printf出来比比,应该就能看出来了
#define offs(s,m) (size_t)&(((s *)0)->m) 不行就合并到一个工程看看还有问题没 |
22
secondwtq 2015-07-27 03:26:06 +08:00 1
我个人倾向于@mljack 的观点。我最近恰好被这个问题坑得很惨(因为库和客户程序都是 Xcode 下类似的配置编译,所以并没有对齐问题,但是细节上有出入)。
我并不是非常熟悉调试的那一套理论(尤其是 VS 下面调试),我认为楼主可以尝试探索周围的成员变量地址,看看到哪里的时候两边的 offset 是一致的。 从截图中可以注意到: `(*((qte.exe!cocos2d::Scene*)(&(*((qte.exe!MainGameScene*)(scene))))))._navMesh`,使用的应该是客户程序的偏移量。 `&(scene)->_navMesh` 貌似使用的是 dll 里的偏移量。这个调试信息有没有保存我并不清楚,是不是跟图中现在貌似正处于 dll 中代码的 context 下也不清楚。 |
23
forcecharlie 2015-07-27 10:20:34 +08:00
@nozama 构建系统一般只会检测 源文件的时间戳,然而,不一定检测头文件的时间戳,只有当 目标的时间戳比依赖的时间戳旧时,构建才会再一次发生,重新生成不是这样。
|
24
secondwtq 2015-07-27 14:56:48 +08:00
@forcecharlie 此话怎讲?一般情况下,某个 Compilation Unit (.c/cpp) 所 include 的 header 应该算是其依赖吧,那么这些 header 中再次引入的其他 header 算不算呢?如果先改动了 header 再改动 cpp(这样 cpp 的时间戳是最新的),是否会触发编译呢?
|
25
forcecharlie 2015-07-27 22:53:55 +08:00
@secondwtq 构建文件并没有解析 include 的能力,以 Makefile 为例,最好在依赖中显式的指明 头文件,如果一个构建系统并没有将头文件的添加到依赖,那么头文件的修改也不会有新的编译响应,当然,一些构建系统会根据文件 Hash 来检测,这些就需要存储到一个数据库文件或者是缓存文件。改动了 cpp 基本上都会触发编译。
Hello.obj:Hello.cpp Hello.h cl -c Hello.cpp |
26
secondwtq 2015-07-27 23:58:15 +08:00
@forcecharlie 这倒是,Makefile 这种比较直接的底层工具不会去检测这种特定的东西。
高级的工具貌似有专门去解决,我一般用 CMake,在 generate 的过程中会提取出 header 的依赖(据说是根据编译器提供的信息)。Xcode 也会自动触发编译,VS 大概不会没有。 |