|
| 1 | +# How to wrap OpenVINO interfaces with C |
| 2 | + |
| 3 | +The library `openvino_c` implements most C++ interfaces provided in OpenVINO with C. |
| 4 | +This page describes how to wrap C++ interfaces from OpenVINO to C interfaces: |
| 5 | + 1) Define C interface name and input parameters |
| 6 | + 2) Check the validation of input parameters |
| 7 | + 3) Convert C input parameters to C++ interface parameters |
| 8 | + 4) Call C++ interface and get return object |
| 9 | + 5) Convert C++ return object to C object |
| 10 | + |
| 11 | +```mermaid |
| 12 | +flowchart LR |
| 13 | + subgraph c_wrap_process[Wrapping C++ by C Flow] |
| 14 | + c_interface["Define C name"] |
| 15 | + c_check_parameter["Input parameter checking"] |
| 16 | + c_return_invalid["return ov_status_e::INVALID_C_PARAM"] |
| 17 | +
|
| 18 | + subgraph c_wrap_call_cpp[Try Call C++] |
| 19 | + c_parameter_convert["convert C parameters to C++ parameters"] |
| 20 | + c_call_cpp_interface["call C++ interface"] |
| 21 | + cpp_parameter_convert["convert C++ returned objects to C object"] |
| 22 | + end |
| 23 | + |
| 24 | + c_return_success["return ov_status_e::OK"] |
| 25 | + c_return_exception["catch EXCEPTION and return"] |
| 26 | +
|
| 27 | + c_interface-->c_check_parameter |
| 28 | +
|
| 29 | + c_check_parameter--valid-->c_parameter_convert |
| 30 | + c_check_parameter--invalid-->c_return_invalid |
| 31 | +
|
| 32 | + c_parameter_convert-->c_call_cpp_interface |
| 33 | + c_call_cpp_interface-->cpp_parameter_convert |
| 34 | +
|
| 35 | + cpp_parameter_convert-->c_return_success |
| 36 | + c_wrap_call_cpp-->c_return_exception |
| 37 | + end |
| 38 | +``` |
| 39 | + |
| 40 | +All C-provided interfaces can be classified into three types of methods: |
| 41 | +- Wrap C++ interface to create an object |
| 42 | +- Wrap C++ interface to operate an object |
| 43 | +- Interfaces implemented by C |
| 44 | + |
| 45 | +## Wrap C++ interface to create an object |
| 46 | +Like the C++ programming create `class` instance, C also need to create related object such as creating `ov::Core`, `ov::Model`, `ov::InferRequest` and so on. C wrap this operation directly and save a shared pointer to the object(C++) back to C `struct` object. Based on the above wrapping method, example about creating `ov::Core` instance will be introduction for more details to illustrate how to wrap C++ interfaces. |
| 47 | + |
| 48 | +Thinking about the C++ interface: |
| 49 | + |
| 50 | +https://github.com/openvinotoolkit/openvino/blob/d96c25844d6cfd5ad131539c8a0928266127b05a/src/inference/include/openvino/runtime/core.hpp#L46-L58 |
| 51 | + |
| 52 | +C wrap as following: |
| 53 | + |
| 54 | +https://github.com/openvinotoolkit/openvino/blob/d96c25844d6cfd5ad131539c8a0928266127b05a/src/bindings/c/src/ov_core.cpp#L48-L64 |
| 55 | + |
| 56 | +Because the C++ core create API has default parameter `const std::string& xml_config_file = {}`, C has to create two APIs for it. For default parameter missing case, C calls the func with default parameter but value is NULL. So the following introduction focus on the func with default parameter. The first define the API name `ov_core_create_with_config` and than do the input parameters checking. For core creates no need C parameters convert to C++, call C++ API directly and make a shared pointer `std::make_shared<ov::Core>(xml_config_file)`. Than get result from C++ call and save to C object `*core = _core.release()`. If no error, return success `return ov_status_e::OK;`. Note that almost all C interfaces pass a pointer parameter to save result, which also need to be freed after use. |
| 57 | + |
| 58 | +## Wrap C++ interface to operate object |
| 59 | +C++ interface provides many ways to operate instances, such as set/get property for core, infer request do infer, get info from model and so on. C also need provides those related operations. Here is an example about doing inference: |
| 60 | + |
| 61 | +https://github.com/openvinotoolkit/openvino/blob/d96c25844d6cfd5ad131539c8a0928266127b05a/src/bindings/c/src/ov_infer_request.cpp#L236-L247 |
| 62 | + |
| 63 | +This interface call C++ API directly without return value need to save. But need to note the input parameter, which is a C `struct` pointer for providing operation object. |
| 64 | + |
| 65 | +## C implement interface |
| 66 | +To provide more convenience for C users, C implements some C++ class by rewriting including `shape`, `dimension`, `partial shape` and so on. Because of this, C also implements some interface to create/operate C `struct` objects, which also needs the conversion from C object to C++ object before C++ call. |
| 67 | + |
| 68 | +For example, the C `shape` created by |
| 69 | + |
| 70 | +https://github.com/openvinotoolkit/openvino/blob/d96c25844d6cfd5ad131539c8a0928266127b05a/src/bindings/c/src/ov_shape.cpp#L17-L33 |
| 71 | + |
| 72 | +As we can see no C++ interface called. But when the object needs to be used for C++ call, which will provide info to create the related C++ object before call, such as: |
| 73 | + |
| 74 | +https://github.com/openvinotoolkit/openvino/blob/d96c25844d6cfd5ad131539c8a0928266127b05a/src/bindings/c/src/ov_tensor.cpp#L41-L55 |
| 75 | + |
| 76 | +The tensor create needs to specify the shape info, so C shape need to be converted to C++ class before C++ interface using. Vice versa, the object needs to convert to C rewriting object for C users convenience. |
| 77 | + |
| 78 | + ## See also |
| 79 | + * [OpenVINO™ README](../../../../README.md) |
| 80 | + * [C API developer guide](../README.md) |
| 81 | + * [C API Reference](https://docs.openvino.ai/latest/api/api_reference.html) |
0 commit comments