本帖最后由 hi201803 于 2018-3-19 21:44 编辑 & ?# k2 \" @% ? o+ y. J6 q5 A0 p 版本: SWstm32 V2.4 现象: 使用stm32cubeMX 生成 代码, 然后再 SWstm32 中转换成 c++ 项目。 c++虚函数执行 出错。 下面的代码, 无法正确运行:( 在keil 中可正确运行 ). 代码只是示例,非实际项目中遇错代码.( I! H3 ]0 X1 L) g5 C; V% T2 B6 B class class_18 @ e4 f3 z9 Q% H; J) \ { public: int a, b; virtual void send ( int , char*) =0;; N$ m" [- X' t# Z) o; ] void fun( int i1 , char* cs1) { send (i1,cs1); };( ]2 `% k; `8 t9 T/ b9 ` };; P* ?+ \0 `* L2 H ]: E- X3 k class class_2 : public class_14 T* L, J( o* |( H# Z { public:; y- u3 u4 E' d. `9 l& l int a1, b1;, a4 P, T0 _; |; q# H/ M virtual void send ( int , char*) { } ; } aclass; extern "C" void fun1(void);% D5 i$ O0 \/ I z+ b7 s3 i void fun1(void): k2 L6 L* \8 l0 E {; _" d% l% r: m5 } int i=1; char cs[8]; aclass.fun( 1, cs); // 函数fun 调用class_1::send , 应该变成调用 class_2:: send。 但调用一个莫名其妙的地址了.最后导致异常中断. g' ^1 E" M4 c. G6 N( q0 x } ====2018/03/14 增加: 测试以上代码 ================================== / z; q8 N5 h: _6 w4 E+ h8 H U // 上面橙黄色代码是添加的,为了使编译通过. 不影响测试. // 然后再 main 函数中调用 fun1.4 X8 r. N. X7 D) v9 m extern void fun1(void); void main(void) {. ^5 b7 w. W( E8 q0 T) b fun1( ); while(1); }) }1 J( F7 |5 X+ s( u* o+ z9 h* | 测试结果: 1. 使用stm32cubeMX 生成 代码, 然后再 SWstm32 中转换成 c++ 项目,添加以上代码, 测试不通过 !!!! 。1 d2 |. H: y. V 2. 如果直接使用 swstm32 生成 C++ 程序, 添加以上代码, 测试通过 !!!!!! 。- -$ |0 F+ j/ p Y+ b& U ~# d7 I3 C ====2018/03/15 增加: 原因 =================================== 原因: SWstm32 把 c 项目转化为 c++ 时, 没有修改启动代码,全局变量 的类实例 没有初始化,类实例指向虚表的指针不正确。 6 d5 K/ }' _) X4 E a2 ^, e& u 解决办法 1 : 在初始化代码中, 调用 main 函数之前, 执行: bl __libc_init_array% k4 _2 a( |3 z, N! ]" ` 解决办法 2 : 直接拷贝 使用 swstm32 生成 C++ 项目的初始化代码, 替换原启动代码。- a1 l% X7 M# s# u/ g 3 K$ l+ ]3 H Z3 q/ C |
我又测试了代码, 在swstm32 的开发环境中测试的。
在一楼中添加了测试结果。
奇怪,5 W2 j7 \/ e4 Q" G# d9 t1 T, h
c转换成c++项目中, 在map文件里面只看到 class_2 的虚表, 没有class_1的虚表。 运行不正常.
但 直接使用SWStm32 生成的项目中, map文件里面看到 class_1, 和class_2 的虚表, 运行正常./ P: G3 Q! D. M0 E) |' v
我对比两项目的c++ 编译,连接,及 链接文件, 居然没发现明显的不一样。 真是奇怪。
把两个链接脚本文件 diff 一下,某处细节肯定有差异。还有,可以尝试一下替换 GCC,用 Arm 打包的 GCC 7.2 换下 Ac6 的版本。
# ^( o2 C7 K# k9 e. o. ^
把链接脚本文件 都弄成一样的了,还是不行。
原因找到了:
启动代码没有调用 全局变量 类实例 的初始化函数,造成类实例指向虚表的指针不正确.