散分, C++/CLI 怪异行为, 走过路过不要错过,该如何处理
散分, C++/CLI 怪异行为, 走过路过不要错过
先上码子:
程序输出:
f been called
0
异常
没去搞 IL 看是怎么回事, 大家来说说 f 为啥使用空实例 handle 就可以调用来,
f 内部对成员的访问也挺好玩
这是做 clr host 时碰到的, 实际代码
这是设计上的考虑? 还是怎么回事.
------解决方案--------------------
不要错过
------解决方案--------------------
managed c++不懂
------解决方案--------------------
还有更怪的呢
例如你的代码在如果f 里访问this指针 会报错
如果你改成这样
A a;
a.f();则不会
毕竟原生c++和 .net 有太大差别,把二者合为一体,很多东西,不能像c# vb.net 那样。
还需要编译器作些工作
------解决方案--------------------
对象不存在,(this指针无效),如果不访问对象中的数据成员和虚表则不会出问题,反之访问对象中的数据或者调用虚函数等情况就会产生异常。
------解决方案--------------------
看看atl的源码
#define offsetof(s,m) (size_t)&reinterpret_cast<const volatile char&>((((s *)0)->m))
stddef.h
------解决方案--------------------
学习一下!
------解决方案--------------------
学习学习,楼主辛苦了。
------解决方案--------------------
学习一下!
------解决方案--------------------
学习
------解决方案--------------------
收藏。。。
------解决方案--------------------
学习
------解决方案--------------------
路过
------解决方案--------------------
收藏
------解决方案--------------------
MARK 学习
------解决方案--------------------
学习学习,楼主辛苦了。
------解决方案--------------------
学习大家的编程思想
------解决方案--------------------
离沙发远了
------解决方案--------------------
123123123123123123123123
------解决方案--------------------
a->f() 因为该方法不是虚方法,所以CLR用call 指令调用,该指令不会检查this指针是否为NULL。
若把f()改成virtual,CLR则用callvirt调用,该指令会检查this指针是否为NULL, 此时调用f()是就出错了.
先上码子:
- C/C++ code
ref class A { private: int i; static int j; public: A() { i = 0; } void f() { System::Console::WriteLine("f been called"); System::Console::WriteLine(j); //System::Console::WriteLine(i);// exception 了 } virtual System::String^ ToString () override { System::Console::WriteLine("tostring been called"); return "A:"; } }; int main() { A^ a;// = nullptr; // 置空一样 a->f(); System::Console::WriteLine(a->ToString()); }
程序输出:
f been called
0
异常
没去搞 IL 看是怎么回事, 大家来说说 f 为啥使用空实例 handle 就可以调用来,
f 内部对成员的访问也挺好玩
这是做 clr host 时碰到的, 实际代码
- C/C++ code
Class^ a = nullptr; try { gcnew Class();// 这里一时忘了对 a 赋值 a->CallShit();// 函数里头访问 this 指针时异常了 }
这是设计上的考虑? 还是怎么回事.
------解决方案--------------------
不要错过
------解决方案--------------------
managed c++不懂
------解决方案--------------------
还有更怪的呢
例如你的代码在如果f 里访问this指针 会报错
如果你改成这样
A a;
a.f();则不会
毕竟原生c++和 .net 有太大差别,把二者合为一体,很多东西,不能像c# vb.net 那样。
还需要编译器作些工作
------解决方案--------------------
对象不存在,(this指针无效),如果不访问对象中的数据成员和虚表则不会出问题,反之访问对象中的数据或者调用虚函数等情况就会产生异常。
------解决方案--------------------
看看atl的源码
#define offsetof(s,m) (size_t)&reinterpret_cast<const volatile char&>((((s *)0)->m))
stddef.h
------解决方案--------------------
学习一下!
------解决方案--------------------
学习学习,楼主辛苦了。
------解决方案--------------------
学习一下!
------解决方案--------------------
学习
------解决方案--------------------
收藏。。。
------解决方案--------------------
学习
------解决方案--------------------
路过
------解决方案--------------------
收藏
------解决方案--------------------
MARK 学习
------解决方案--------------------
学习学习,楼主辛苦了。
------解决方案--------------------
学习大家的编程思想
------解决方案--------------------
离沙发远了
------解决方案--------------------
123123123123123123123123
------解决方案--------------------
a->f() 因为该方法不是虚方法,所以CLR用call 指令调用,该指令不会检查this指针是否为NULL。
若把f()改成virtual,CLR则用callvirt调用,该指令会检查this指针是否为NULL, 此时调用f()是就出错了.
- C/C++ code
virtual void f() { System::Console::WriteLine("f been called "); Console::WriteLine(j); }
------解决方案--------------------