本帖最后由 hi201803 于 2018-3-19 21:44 编辑 7 w6 y9 S- ?( |$ ]9 Z; x. N 版本: SWstm32 V2.4 现象: 使用stm32cubeMX 生成 代码, 然后再 SWstm32 中转换成 c++ 项目。 c++虚函数执行 出错。: \2 v/ Q+ p) G, Y1 c0 r 下面的代码, 无法正确运行:( 在keil 中可正确运行 ). 代码只是示例,非实际项目中遇错代码. class class_1 { public:) R" `+ w0 W7 ?* f" p( i" } int a, b; virtual void send ( int , char*) =0;+ ]- _6 u3 p" ?- D void fun( int i1 , char* cs1) { send (i1,cs1); };6 E9 ~# G' s z" J) | Y }; class class_2 : public class_1 {: P: d+ c/ X' W4 P$ m$ [, z public: int a1, b1; virtual void send ( int , char*) { } ; } aclass; 9 l; p$ S# l) x5 ]# `" s6 j extern "C" void fun1(void); void fun1(void)* ]% s4 j7 z" t9 k { int i=1; char cs[8];" a2 L/ z% b4 U r) w& i- ~ aclass.fun( 1, cs); // 函数fun 调用class_1::send , 应该变成调用 class_2:: send。 但调用一个莫名其妙的地址了.最后导致异常中断.+ Q9 R9 z0 Z/ a4 u2 U/ i- { } ( W1 K* R7 T* G/ p$ ~# B9 p ====2018/03/14 增加: 测试以上代码 ================================== 6 _# K$ d! n/ Q W // 上面橙黄色代码是添加的,为了使编译通过. 不影响测试.) c. x' N1 f% Q! _3 ^2 z$ a // 然后再 main 函数中调用 fun1.' A, C+ z2 ?9 I& b8 p% }/ U extern void fun1(void); void main(void)2 {6 R. w8 V6 A% m# R" E; Q- x { fun1( ); while(1); }7 d' \! f; _& F5 ]; e% a4 y! H3 f 测试结果: 1. 使用stm32cubeMX 生成 代码, 然后再 SWstm32 中转换成 c++ 项目,添加以上代码, 测试不通过 !!!! 。0 e/ A# a D3 n 2. 如果直接使用 swstm32 生成 C++ 程序, 添加以上代码, 测试通过 !!!!!! 。- -8 C8 j9 m5 S5 P8 f% y& J6 W8 I ====2018/03/15 增加: 原因 ===================================1 d4 [, F6 o( Q; W) H* ` 原因: SWstm32 把 c 项目转化为 c++ 时, 没有修改启动代码,全局变量 的类实例 没有初始化,类实例指向虚表的指针不正确。 1 d1 `4 C) U& X/ D7 g6 t 解决办法 1 : 在初始化代码中, 调用 main 函数之前, 执行: bl __libc_init_array2 F0 s8 d) s) T& p 解决办法 2 : 直接拷贝 使用 swstm32 生成 C++ 项目的初始化代码, 替换原启动代码。 5 |5 t- A8 I, J* o - j+ H% l$ a5 R+ k- V. }3 _2 B( } |
我又测试了代码, 在swstm32 的开发环境中测试的。
在一楼中添加了测试结果。
奇怪,3 V7 {% {( A3 c+ \
c转换成c++项目中, 在map文件里面只看到 class_2 的虚表, 没有class_1的虚表。 运行不正常.; K( a, e" U6 m, x9 A5 R& J( |3 {
但 直接使用SWStm32 生成的项目中, map文件里面看到 class_1, 和class_2 的虚表, 运行正常./ w% p* k* ~) U7 T
8 J- M0 r$ S! j& o- ^
我对比两项目的c++ 编译,连接,及 链接文件, 居然没发现明显的不一样。 真是奇怪。
把两个链接脚本文件 diff 一下,某处细节肯定有差异。还有,可以尝试一下替换 GCC,用 Arm 打包的 GCC 7.2 换下 Ac6 的版本。
7 ^- D- k0 r/ y# Q1 w+ g7 v( J0 a
把链接脚本文件 都弄成一样的了,还是不行。
原因找到了: / U3 z. a/ D Y( L6 {
启动代码没有调用 全局变量 类实例 的初始化函数,造成类实例指向虚表的指针不正确.