公司项目主体部分用c++,而ui部分用lua写,所以选择了用quick框架。项目先开发了ios/mac版,这两天试着配置其win32工程,遇到一些问题,记录一下(纯c++版本cocos2dx配置方法应该也是类似的)。
先配debug模式:
把c++文件都添到工程中去,并在附加包含目录下配置c++文件的搜索路径。然后编译会遇到一些问题:
一,win32下fullPathForFilename函数与ios/mac下行为不一致的问题。
fullPathForFilename当传入的参数是文件夹路径时,ios/mac下与win32下行为不同。
在ios/mac下fullPathForFilename如果传入的参数是文件夹路径且路径存在,就能返回正确的全路径。但在win32下,如果传入的参数是文件夹路径,则将原样返回传入的参数。
由于项目中使用了fullPathForFilename来获得文件夹全路径,所以在ios/mac下正常,而在win32下得不到正确结果。解法见:http://www.cnblogs.com/wantnon/p/4295876.html
二,找不到pdb调试信息error。
将 属性-> C/C++ -> 常规 ->调试信息格式 设置为 C7 兼容(/Z7)。
三,拷贝资源脚本。
此时程序能正常启动了,但运行过程中会因找不到资源而崩溃,原因是一部分资源没有出现在 工作目录$(OutDir)../../../../runtime/win32 之下,事实上 工作目录 本来是空的,是在程序编译过程中的某一阶段,资源被从其所在的文件夹下被拷贝到 工作目录 下。可以在 属性->生成事件->预先生成事件->命令行 中看到如下脚本:
if not exist "$(LocalDebuggerWorkingDirectory)" mkdir "$(LocalDebuggerWorkingDirectory)"
mkdir "$(LocalDebuggerWorkingDirectory)\src"
mkdir "$(LocalDebuggerWorkingDirectory)\res"
xcopy "$(ProjectDir)..\..\..\src" "$(LocalDebuggerWorkingDirectory)\src" /e /Y
xcopy "$(ProjectDir)..\..\..\res" "$(LocalDebuggerWorkingDirectory)\res" /e /Y
copy "$(ProjectDir)..\..\..\config.json" "$(LocalDebuggerWorkingDirectory)\config.json" /Y
可以进入到编辑对话框,然后点“宏(M)>>”打开宏列表来查看$(LocalDebuggerWorkingDirectory)和$(ProjectDir)的定义。
xcopy和copy的区别:xcopy可以复制目录和文件,copy只复制文件。
在quick cocos2dx中lua文件默认放在"$(ProjectDir)..\..\..\src"下,资源文件默认放在"$(ProjectDir)..\..\..\res”下。
在我们的项目中,有一部分资源没有按此规范放到"$(ProjectDir)..\..\..\res”下,而是放到了自己的目录myRes下,因此需要自己添加脚本实现将这部分资源拷贝到 工作目录,添加下面两句即可:
mkdir "$(LocalDebuggerWorkingDirectory)\myRes"
xcopy "$(ProjectDir)..\..\..\c3dToolKit\toolKitRes" "$(LocalDebuggerWorkingDirectory)\myRes" /e /Y
此时debug下可以正确运行了。
再配置release模式:
同样按上面方法配置release模式后发现无法正常运行。
四,.c文件报错。
一些纯c写成的第三方库,例如sqlite3.c等文件会报一些语法错误,例如 void*不能隐式转化为char*, 在结构体A内部定义的结构体B在外部使用时如果不写成struct A::B而仅写成struct B则找不到定义 等。产生这些错误的原因显然是编译器按照c++的标准去编译c了,当然将这些.c文件中的c语法改写为c++是可以解决问题的,但由于如sqlite3.c这样的大文件需要修改的地方实在太多,所以改成c++语法的方法不现实。后来发现在 属性->c/c++ ->高级->编译为 中可以选择“编译为c++代码(/TP)”或"编译为c代码(/TC)",而且这个属性是可以每个文件单独设置的,细看debug模式的设置,发现是整个工程的“编译为”属性设置为"编译为c++代码",而如sqlite3.c等纯c文件的“编译为”属性设置为“默认值”,另外整个工程的“强制包含文件”属性设置为“algorithm”,而如sqlite3.c等纯c文件的"强制包含文件"属性置空。(如果纯c文件的"强制包含文件"属性不置空,而设置为"algorithm"的话,会报 error C2054: 在“using”之后应输入“(” 的错误。)于是release模式下也照此设置,则问题解决。
五,error LNK2005: xxx已经在 lua51.lib(lua51.dll) 中定义。
对比debug和release的 属性->连接器->输入->附加依赖项,其中release下多了一个lua51.lib,而debug下没有这一项,将release下的lua51.lib去掉,就不再报此error。
六,“工作目录”和“命令”。
属性->调试->命令,属性->调试->工作目录,这两项release与debug配置不一样,由于debug配置已确信是可行的,索性将release配置改成与debug相同:
命令:$(OutDir)../../../../runtime/win32/$(TargetFileName)
工作目录:$(OutDir)../../../../runtime/win32
其中“命令”是可执行程序的路径,“工作目录”是资源目录。
通过查看宏值可以发现 $(LocalDebuggerWorkingDirectory) 与 工作目录 是保持一致的。
七,丢失dll的问题。
编译通过,但启动时弹出“无法启动此程序,因为计算机中丢失xxx.dll”报错。
是因为dll没拷贝到 工作目录 下。查看debug模式下的 属性->生成事件->后期生成事件,发现有下面脚本:
xcopy /Y /Q "$(OutDir)*.dll" "$(ProjectDir)..\..\..\runtime\win32\"
而release模式下却没有此段脚本,于是把同样的脚本添加到release模式下,问题即可解决。
八,项目及依赖项目release模式下编译优化设置。
通常debug模式下将编译优化全关掉即可。而对于release模式,由于目的是生成运行速度快的可执行程序,所以应将编译优化选项选为“使速度最大化”,另外不要忘记检查各依赖项目(libbox2d,libcocos2d,libluacocos2d,libSpine)的release模式是否也设置了“使速度最大化”,因为我发现我这个项目的release模式下各依赖项目的编译优化在默认情况下并没有设成"使速度最大化"。