|
本帖最后由 hi201803 于 2018-3-19 21:44 编辑 . z% h' n+ i y* Z, N3 [; |/ X. T( r+ X 版本: SWstm32 V2.4% L4 A& m$ k2 |- y- k9 U 现象: 使用stm32cubeMX 生成 代码, 然后再 SWstm32 中转换成 c++ 项目。 c++虚函数执行 出错。 下面的代码, 无法正确运行:( 在keil 中可正确运行 ). 代码只是示例,非实际项目中遇错代码.4 g7 E3 H; v& G- o+ B. n. V% V 5 h, o$ j" Z, Z# r x% E# ? class class_1 {4 l3 U, F; _. \; {+ Z public: int a, b; virtual void send ( int , char*) =0; void fun( int i1 , char* cs1) { send (i1,cs1); };3 G5 h$ n; Q: P. ]7 |0 U. y& k }; class class_2 : public class_1- B, Z, t! ^* B8 \4 k {5 N4 @5 {5 U" g8 o, Y! W2 K public:0 _( w D: q$ M7 H int a1, b1;0 u7 u1 @8 L( j& o5 { virtual void send ( int , char*) { } ;- R6 `# Z( ?) ~. d/ D } aclass; % m L% ?+ `/ n5 v$ n( I2 { * m* p5 A5 }( _. o1 ^ extern "C" void fun1(void);' _% u; B# o) J0 G7 u& d void fun1(void) { int i=1;' H ~& B8 ^+ L" h& i char cs[8];0 b2 q5 {+ X$ i8 Y; G aclass.fun( 1, cs); // 函数fun 调用class_1::send , 应该变成调用 class_2:: send。 但调用一个莫名其妙的地址了.最后导致异常中断.% h! T+ X$ u1 [; l" C- @4 f0 e5 R } " F( l, Y! d5 J ====2018/03/14 增加: 测试以上代码 ==================================: w& y: f6 |0 G: [0 K3 j" w' s 0 f" B$ m0 E2 l0 j5 F! h8 w2 F& b // 上面橙黄色代码是添加的,为了使编译通过. 不影响测试. // 然后再 main 函数中调用 fun1.2 l5 I9 C$ e/ o' j4 S; g) E extern void fun1(void);$ f0 W1 m2 l) A+ l5 T" X; q# H8 w void main(void)5 ^; ~5 ~% u$ A7 A; Y { fun1( ); while(1); }8 F, q4 u9 Y: @5 z s6 X 测试结果: # X6 O. N! E- a2 h 1. 使用stm32cubeMX 生成 代码, 然后再 SWstm32 中转换成 c++ 项目,添加以上代码, 测试不通过 !!!! 。! t3 l- [* A1 ~. Z- }' I 2. 如果直接使用 swstm32 生成 C++ 程序, 添加以上代码, 测试通过 !!!!!! 。- -# U% t; b1 K ]9 s' c ====2018/03/15 增加: 原因 ===================================; V1 [8 r# A/ x 原因: SWstm32 把 c 项目转化为 c++ 时, 没有修改启动代码,全局变量 的类实例 没有初始化,类实例指向虚表的指针不正确。 $ d1 D* `# }; {* v 解决办法 1 : 在初始化代码中, 调用 main 函数之前, 执行: bl __libc_init_array 解决办法 2 : 直接拷贝 使用 swstm32 生成 C++ 项目的初始化代码, 替换原启动代码。6 @' \% ` W f8 p5 K1 w! z7 y 2 E: Y# X0 r& W/ `. L7 _ 2 q5 z% a% a1 [( r" }' c2 U . G8 q/ Q+ \7 u& h& p5 l" ~ |
微信公众号
手机版
我又测试了代码, 在swstm32 的开发环境中测试的。
在一楼中添加了测试结果。
奇怪,, j! T7 d$ E3 ]- C
c转换成c++项目中, 在map文件里面只看到 class_2 的虚表, 没有class_1的虚表。 运行不正常.
但 直接使用SWStm32 生成的项目中, map文件里面看到 class_1, 和class_2 的虚表, 运行正常.5 P8 ]5 Y( y: k. V! o
& i- E6 Y& q3 S. `; m% S
我对比两项目的c++ 编译,连接,及 链接文件, 居然没发现明显的不一样。 真是奇怪。
把两个链接脚本文件 diff 一下,某处细节肯定有差异。还有,可以尝试一下替换 GCC,用 Arm 打包的 GCC 7.2 换下 Ac6 的版本。
把链接脚本文件 都弄成一样的了,还是不行。
原因找到了:
启动代码没有调用 全局变量 类实例 的初始化函数,造成类实例指向虚表的指针不正确.