_purecall & _get_purecall_handler &  _set_purecall_handler

原文:https://docs.microsoft.com/zh-cn/cpp/c-runtime-library/reference/purecall?view=vs-2019

一、_purecall

默认纯虚拟函数调用错误处理程序。 当调用纯虚拟成员函数时,编译器生成调用此函数的代码。

语法

C复制

extern "C" int __cdecl _purecall();

备注

_purecall函数是 Microsoft C++编译器的特定于 Microsoft 的实现详细信息。 此函数不可以直接通过代码调用,也没有任何公用标头声明。 之所以在这里讨论此函数,是因为它是 C 运行时库的公用导出。

对纯虚拟函数的调用出错,因为它没有实现。 调用纯虚拟函数时,编译器将生成代码以调用 _purecall错误处理程序函数。 默认情况下 ,_purecall终止程序。 在终止之前,如果已为进程设置了 _purecall_handler函数,则_purecall函数将调用该函数。 可以安装自己的错误处理程序进行纯虚拟函数调用,以捕获这些调用用于调试和报告目的。 要使用自己的错误处理程序,请创建具有 _purecall_handler签名的函数,然后使用_set_purecall_handler使其成为当前处理程序。

默认情况下,此函数的全局状态范围为应用程序。 要更改此情况,请参阅CRT 中的全局状态

要求

_purecall函数没有标头声明。 _purecall_handler类型def在 stdlib.h>中<定义。

二、_get_purecall_handler、 _set_purecall_handler

获取或设置纯虚函数调用的错误处理程序。

语法

C++复制

typedef void (__cdecl* _purecall_handler)(void);
_purecall_handler __cdecl _get_purecall_handler(void);
_purecall_handler __cdecl _set_purecall_handler(
   _purecall_handler function
);

参数

函数
要在调用纯虚函数时调用的函数。 _Purecall_handler函数必须具有 void 返回类型。

返回值

上一个 _purecall_handler。 如果没有上一个处理程序,则返回nullptr 。

备注

_Get_purecall_handler和 _Set_purecall_handler函数是 Microsoft 特定的,仅适用于C++代码。

对纯虚拟函数的调用出错,因为它没有实现。 默认情况下,在调用纯虚函数时,编译器将生成代码来调用错误处理程序函数,这将终止该程序。 可以安装自己的错误处理程序进行纯虚拟函数调用,以捕获这些调用用于调试和报告目的。 若要使用自己的错误处理程序,请创建具有 _purecall_handler签名的函数,然后使用 _set_purecall_handler使其成为当前处理程序。

由于每个进程只有一个 _purecall_handler ,因此当调用 _set_purecall_handler时,它会立即影响所有线程。 任一线程上的最后一个调用方将设置该处理程序。

若要还原默认行为,请使用nullptr参数调用 _set_purecall_handler 。

要求

表 1
例程所返回的值必需的标头
_get_purecall_handler、 _set_purecall_handler<cstdlib> 或 <stdlib.h>

有关兼容性信息,请参阅 兼容性

示例

C++复制

// _set_purecall_handler.cpp
// compile with: /W1
#include <tchar.h>
#include <stdio.h>
#include <stdlib.h>

class CDerived;
class CBase
{
public:
   CBase(CDerived *derived): m_pDerived(derived) {};
   ~CBase();
   virtual void function(void) = 0;

   CDerived * m_pDerived;
};

class CDerived : public CBase
{
public:
   CDerived() : CBase(this) {};   // C4355
   virtual void function(void) {};
};

CBase::~CBase()
{
   m_pDerived -> function();
}

void myPurecallHandler(void)
{
   printf("In _purecall_handler.");
   exit(0);
}

int _tmain(int argc, _TCHAR* argv[])
{
   _set_purecall_handler(myPurecallHandler);
   CDerived myDerived;
}

Output复制

In _purecall_handler.
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据提供的引用内容,我们可以得知在CM3中,硬fault是一种系统异常,而且有多种类型。如果想要强制跳出HardFault_Handler,可以使用以下方法: ```c // 定义一个函数指针 typedef void (*pFunction)(void); // 定义一个函数,用于获取堆栈指针 __asm uint32_t get_PSP(void) { MRS R0, PSP BX LR } // 定义一个函数,用于获取堆栈底部地址 uint32_t get_stack_bottom(void) { uint32_t stack_bottom = 0; uint32_t stack_size = 0; uint32_t psp_value = 0; // 获取堆栈指针 psp_value = get_PSP(); // 获取堆栈大小 stack_size = *(uint32_t *)psp_value; // 计算堆栈底部地址 stack_bottom = psp_value - stack_size + 4; return stack_bottom; } // 定义一个函数,用于强制跳出HardFault_Handler void jump_to_app(void) { uint32_t app_addr = 0; pFunction Jump_To_Application; // 获取应用程序的起始地址 app_addr = *(volatile uint32_t *)(0x08000000 + 4); // 判断应用程序地址是否合法 if ((app_addr & 0x2FFE0000) == 0x20000000) { // 关闭所有中断 __disable_irq(); // 设置堆栈指针 __set_MSP(*(volatile uint32_t *)0x08000000); // 跳转到应用程序 Jump_To_Application = (pFunction)app_addr; Jump_To_Application(); } } // 定义HardFault_Handler函数 void HardFault_Handler(void) { uint32_t stack_bottom = 0; // 获取堆栈底部地址 stack_bottom = get_stack_bottom(); // 判断是否需要跳转到应用程序 if (*(volatile uint32_t *)stack_bottom == 0x12345678) { jump_to_app(); } // 此处可以添加其他处理代码 } ``` 以上代码中,我们定义了一个函数指针pFunction,用于指向应用程序的起始地址。然后我们定义了一个get_PSP函数,用于获取堆栈指针。接着我们定义了一个get_stack_bottom函数,用于获取堆栈底部地址。最后我们定义了一个jump_to_app函数,用于跳转到应用程序。在HardFault_Handler函数中,我们首先获取堆栈底部地址,然后判断是否需要跳转到应用程序,如果需要就调用jump_to_app函数跳转到应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值