你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

SWstm32 转换c项目到c++,补遗

[复制链接]
hi201803 发布时间:2018-3-14 00:57
本帖最后由 hi201803 于 2018-3-19 21:44 编辑

版本:   SWstm32 V2.4
现象: 使用stm32cubeMX 生成 代码, 然后再 SWstm32 中转换成 c++ 项目。 c++虚函数执行 出错
       下面的代码,  无法正确运行:( 在keil 中可正确运行 ). 代码只是示例,非实际项目中遇错代码.

class  class_1
{
public:
    int a, b;
     virtual void send ( int , char*) =0;
     void fun( int  i1 , char* cs1) {  send (i1,cs1); };
};
class  class_2 :  public class_1
{
public:
    int a1, b1;
     virtual void send ( int , char*)  {     } ;
}  aclass;

extern "C" void fun1(void);
void fun1(void)
{
    int i=1;
    char cs[8];
   aclass.fun( 1, cs);   //  函数fun  调用class_1::send , 应该变成调用 class_2:: send。 但调用一个莫名其妙的地址了.最后导致异常中断.
}   
====2018/03/14  增加:   测试以上代码  ==================================

// 上面橙黄色代码是添加的,为了使编译通过. 不影响测试.
// 然后再 main 函数中调用 fun1.
extern void fun1(void);
void main(void)
{
   fun1( );
  while(1);
}
测试结果:  
   1.  使用stm32cubeMX 生成 代码, 然后再 SWstm32 中转换成 c++ 项目,添加以上代码, 测试不通过 !!!! 。
   2.  如果直接使用 swstm32 生成 C++ 程序, 添加以上代码, 测试通过 !!!!!! 。-
-
====2018/03/15  增加:  原因  ===================================
原因:      SWstm32 把 c 项目转化为 c++ 时, 没有修改启动代码,全局变量 的类实例 没有初始化,类实例指向虚表的指针不正确。
解决办法 1 :  在初始化代码中, 调用 main 函数之前, 执行:  bl __libc_init_array
解决办法 2 : 直接拷贝 使用 swstm32 生成 C++ 项目的初始化代码, 替换原启动代码。






ac6版本.jpg
收藏 1 评论7 发布时间:2018-3-14 00:57

举报

7个回答
maxtch 回答时间:2018-3-14 05:51:42
vtable 在数据段里面吗?
Mandelbrot_Set 回答时间:2018-3-14 09:26:08
示例代码vs2015编译不过。。。
hi201803 回答时间:2018-3-14 16:05:37
本帖最后由 hi201803 于 2018-3-20 13:54 编辑
Mandelbrot_Set 发表于 2018-3-14 09:26
示例代码vs2015编译不过。。。

我又测试了代码, 在swstm32 的开发环境中测试的。
在一楼中添加了测试结果。
hi201803 回答时间:2018-3-14 17:14:50
maxtch 发表于 2018-3-14 05:51
vtable 在数据段里面吗?

奇怪,
c转换成c++项目中, 在map文件里面只看到 class_2 的虚表, 没有class_1的虚表。 运行不正常.
但  直接使用SWStm32 生成的项目中, map文件里面看到 class_1, 和class_2 的虚表, 运行正常.

我对比两项目的c++ 编译,连接,及 链接文件, 居然没发现明显的不一样。 真是奇怪。
maxtch 回答时间:2018-3-14 21:00:51
hi201803 发表于 2018-3-14 17:14
奇怪,
c转换成c++项目中, 在map文件里面只看到 class_2 的虚表, 没有class_1的虚表。 运行不正常.
但  ...

把两个链接脚本文件 diff 一下,某处细节肯定有差异。还有,可以尝试一下替换 GCC,用 Arm 打包的 GCC 7.2 换下 Ac6 的版本。
hi201803 回答时间:2018-3-14 22:33:26
maxtch 发表于 2018-3-14 21:00
把两个链接脚本文件 diff 一下,某处细节肯定有差异。还有,可以尝试一下替换 GCC,用 Arm 打包的 GCC 7. ...


把链接脚本文件 都弄成一样的了,还是不行。
hi201803 回答时间:2018-3-15 22:46:00
maxtch 发表于 2018-3-14 21:00
把两个链接脚本文件 diff 一下,某处细节肯定有差异。还有,可以尝试一下替换 GCC,用 Arm 打包的 GCC 7. ...

原因找到了:  
启动代码没有调用 全局变量 类实例 的初始化函数,造成类实例指向虚表的指针不正确.

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版