不喜欢C++,不规范的C++代码的移植简直就是一场恶梦,即使是在同一种编译器的不同版本间移植也会令人痛苦不堪。Mozilla甚至给出了一个编码规范,以减少跨平台/跨编译器移植的麻烦。不符合该规范的代码一律被认为BUG,即使代码的功能正确。
不同编译器编出来的C++代码通常是不能混用的。因为C++有个符号mangling的问题,不同的编译器有不同的mangling方法,导致符号不通用。Solaris上的Java虚拟机是用Sun compiler编译的,因此如果你有JNI代码是C++写的,你应该用Sun compiler编译JNI代码。(当然Sun compiler是免费的)。编译各种操作系统平台的JNI代码的建议编译选项见Kelly O'Hair的blog。
Sun compiler编译可执行程序时会自动链接 -lCstd -lCrun -lm -lc ,但编共享库时却不会。所以编共享库时应该显式地加上这些链接选项。
Sun compiler 也同时提供标准C++库的stlport实现,编译时可以加上-library=stlport4以使用stlport的实现而不是自带的libCstd.so.1。但这二者在同一程序中不能混用。
如果用DTrace来调试C++程序,函数名要使用mangle过的符号,因为DTrace不认识C++(mdb也是这样)。想得到mangle过的符号可以通过nm -C <binary name> 得到。如果要跟踪函数的参数,第一个参数通常应该是arg1而不是arg0,因为C++中类成员函数映射成C代码后第一个参数一般都是this指针。比如下面的DTrace脚本跟踪某个函数的调用过程:
#!/usr/sbin/dtrace -qFs
pid$target::__xxxxxx_:entry
{
self->traced=1;
printf("thread #%d is doing %s n", tid, copyinstr(arg1)); /* suppose arg1 type is char* */
}
pid$target::__xxxxxx_:return
pid$target:::entry
/self->traced/
{
printf("thread #%d is calling %s .n", tid, probefunc);
}
pid$target:::return
/self->traced/
{
printf("thread #%d returns from %s .n", tid, probefunc);
}
查看本文来源