Merge branch 'feature/cpp_exceptions_example' into 'master'
examples: add C++ exception handling example See merge request idf/esp-idf!3178
This commit is contained in:
commit
8893438f08
7 changed files with 142 additions and 0 deletions
|
@ -119,4 +119,5 @@ Enabling exception handling normally increases application binary size by a few
|
|||
|
||||
If an exception is thrown, but there is no ``catch`` block, the program will be terminated by ``abort`` function, and backtrace will be printed. See :doc:`Fatal Errors <fatal-errors>` for more information about backtraces.
|
||||
|
||||
See :example:`system/cpp_exceptions` for an example of C++ exception handling.
|
||||
|
||||
|
|
9
examples/system/cpp_exceptions/Makefile
Normal file
9
examples/system/cpp_exceptions/Makefile
Normal file
|
@ -0,0 +1,9 @@
|
|||
#
|
||||
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
|
||||
# project subdirectory.
|
||||
#
|
||||
|
||||
PROJECT_NAME := cpp_exceptions_example
|
||||
|
||||
include $(IDF_PATH)/make/project.mk
|
||||
|
41
examples/system/cpp_exceptions/README.md
Normal file
41
examples/system/cpp_exceptions/README.md
Normal file
|
@ -0,0 +1,41 @@
|
|||
# Example: C++ exception handling
|
||||
|
||||
(See the README.md file in the upper level 'examples' directory for more information about examples.)
|
||||
|
||||
This example demonstrates usage of C++ exceptions in ESP-IDF.
|
||||
|
||||
By default, C++ exceptions support is disabled in ESP-IDF. It can be enabled using `CONFIG_CXX_EXCEPTIONS` configuration option.
|
||||
|
||||
In this example, `sdkconfig.defaults` file sets `CONFIG_CXX_EXCEPTIONS` option. This enables both compile time support (`-fexceptions` compiler flag) and run-time support for C++ exception handling.
|
||||
|
||||
Example source code declares a class which can throw exception from the constructor, depending on the argument. It illustrates that exceptions can be thrown and caught using standard C++ facilities.
|
||||
|
||||
## How to use example
|
||||
|
||||
### Configure the project
|
||||
|
||||
Run `make menuconfig` and set serial port under Serial Flasher Options.
|
||||
|
||||
### Build and Flash
|
||||
|
||||
Build the project and flash it to the board, then run monitor tool to view serial output:
|
||||
|
||||
```
|
||||
make -j4 flash monitor
|
||||
```
|
||||
|
||||
(To exit the serial monitor, type ``Ctrl-]``.)
|
||||
|
||||
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
|
||||
|
||||
## Example Output
|
||||
|
||||
```
|
||||
app_main starting
|
||||
In constructor, arg=42
|
||||
In constructor, arg=0
|
||||
In destructor, m_arg=42
|
||||
Exception caught: Exception in constructor
|
||||
app_main done
|
||||
```
|
||||
|
28
examples/system/cpp_exceptions/example_test.py
Normal file
28
examples/system/cpp_exceptions/example_test.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
from __future__ import print_function
|
||||
import os
|
||||
import sys
|
||||
|
||||
test_fw_path = os.getenv('TEST_FW_PATH')
|
||||
if test_fw_path and test_fw_path not in sys.path:
|
||||
sys.path.insert(0, test_fw_path)
|
||||
|
||||
import TinyFW
|
||||
import IDF
|
||||
|
||||
@IDF.idf_example_test(env_tag='Example_WIFI')
|
||||
def test_examples_system_cpp_exceptions(env, extra_data):
|
||||
dut = env.get_dut('cpp_exceptions_example', 'examples/system/cpp_exceptions')
|
||||
# start test
|
||||
dut.start_app()
|
||||
lines = ['app_main starting',
|
||||
'In constructor, arg=42',
|
||||
'In constructor, arg=0',
|
||||
'In destructor, m_arg=42',
|
||||
'Exception caught: Exception in constructor',
|
||||
'app_main done'
|
||||
]
|
||||
for line in lines:
|
||||
dut.expect(line, timeout=2)
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_examples_system_cpp_exceptions()
|
4
examples/system/cpp_exceptions/main/component.mk
Normal file
4
examples/system/cpp_exceptions/main/component.mk
Normal file
|
@ -0,0 +1,4 @@
|
|||
#
|
||||
# "main" pseudo-component makefile.
|
||||
#
|
||||
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
|
|
@ -0,0 +1,56 @@
|
|||
/* C++ exception handling example
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::runtime_error;
|
||||
|
||||
/* A simple class which may throw an exception from constructor */
|
||||
class Throwing
|
||||
{
|
||||
public:
|
||||
Throwing(int arg)
|
||||
: m_arg(arg)
|
||||
{
|
||||
cout << "In constructor, arg=" << arg << endl;
|
||||
if (arg == 0) {
|
||||
throw runtime_error("Exception in constructor");
|
||||
}
|
||||
}
|
||||
|
||||
~Throwing()
|
||||
{
|
||||
cout << "In destructor, m_arg=" << m_arg << endl;
|
||||
}
|
||||
|
||||
protected:
|
||||
int m_arg;
|
||||
};
|
||||
|
||||
/* Inside .cpp file, app_main function must be declared with C linkage */
|
||||
extern "C" void app_main()
|
||||
{
|
||||
cout << "app_main starting" << endl;
|
||||
|
||||
try {
|
||||
/* This will succeed */
|
||||
Throwing obj1(42);
|
||||
|
||||
/* This will throw an exception */
|
||||
Throwing obj2(0);
|
||||
|
||||
cout << "This will not be printed" << endl;
|
||||
} catch (const runtime_error &e) {
|
||||
cout << "Exception caught: " << e.what() << endl;
|
||||
}
|
||||
|
||||
cout << "app_main done" << endl;
|
||||
}
|
3
examples/system/cpp_exceptions/sdkconfig.defaults
Normal file
3
examples/system/cpp_exceptions/sdkconfig.defaults
Normal file
|
@ -0,0 +1,3 @@
|
|||
# Enable C++ exceptions and set emergency pool size for exception objects
|
||||
CONFIG_CXX_EXCEPTIONS=y
|
||||
CONFIG_CXX_EXCEPTIONS_EMG_POOL_SIZE=1024
|
Loading…
Reference in a new issue