Repository: microsoft/onnxruntime
File: include/onnxruntime/core/session/onnxruntime_cxx_api.h (C/C++)

Code before:
//
// #define ORT_API_MANUAL_INIT
// #include <onnxruntime_cxx_api.h>
// #undef ORT_API_MANUAL_INIT
//
// OrtStatus* ORT_API_CALL RegisterCustomOps(OrtSessionOptions* options, const OrtApiBase* api_base) {
//   Ort::InitApi(api_base->GetApi(ORT_API_VERSION));
//   // ...
// }
//
inline void InitApi(const OrtApi* api) noexcept;

namespace detail {
// This is used internally by the C++ API. This class holds the global
// variable that points to the OrtApi.
struct Global {
  static const OrtApi* GetApi() noexcept {
    if (!api_) {
      api_ = DefaultInit();
    }

    return api_;
  }

 private:
  inline static const OrtApi* api_ = nullptr;

  // Has different definitions based on ORT_API_MANUAL_INIT
  static const OrtApi* DefaultInit() noexcept;

  // Public APIs to set the OrtApi* to use.
  friend void ::Ort::InitApi() noexcept;
  friend void ::Ort::InitApi(const OrtApi*) noexcept;
};
}  // namespace detail

#ifdef ORT_API_MANUAL_INIT

inline void InitApi(const OrtApi* api) noexcept { detail::Global::api_ = api; }
inline void InitApi() noexcept { InitApi(OrtGetApiBase()->GetApi(ORT_API_VERSION)); }

#ifdef _MSC_VER
// If you get a linker error about a mismatch here, you are trying to
// link two compilation units that have different definitions for
// ORT_API_MANUAL_INIT together. All compilation units must agree on the
// definition of ORT_API_MANUAL_INIT.
#pragma detect_mismatch("ORT_API_MANUAL_INIT", "enabled")
#endif

inline const OrtApi* detail::Global::DefaultInit() noexcept {
  // When ORT_API_MANUAL_INIT is defined, there's no default init that can

Review comment (bug):
>inline static const OrtApi* api_ = nullptr; [](http://example.com/codeflow?start=2&length=43)

Two questions.
1) Have you considered this to be a function local static?
2) Is this going to be a separate instance in each compilation unit?

Code after:
//
// Example mycustomop.cc:
//
// #define ORT_API_MANUAL_INIT
// #include <onnxruntime_cxx_api.h>
// #undef ORT_API_MANUAL_INIT
//
// OrtStatus* ORT_API_CALL RegisterCustomOps(OrtSessionOptions* options, const OrtApiBase* api_base) {
//   Ort::InitApi(api_base->GetApi(ORT_API_VERSION));
//   // ...
// }
//
inline void InitApi(const OrtApi* api) noexcept;
#endif

namespace detail {
// This is used internally by the C++ API. This class holds the global
// variable that points to the OrtApi.
struct Global {
  static const OrtApi* Api(const OrtApi* newValue = nullptr) noexcept {
    // This block-level static will be initialized once when this function is
    // first executed, delaying the call to DefaultInit() until it is first needed.
    //
    // When ORT_API_MANUAL_INIT is not defined, DefaultInit() calls
    // OrtGetApiBase()->GetApi(), which may result in a shared library being
    // loaded.
    //
    // Using a block-level static instead of a class-level static helps
    // avoid issues with static initialization order and dynamic libraries
    // loading other dynamic libraries.
    //
    // This makes it safe to include the C++ API headers in a shared library
    // that is delay loaded or delay loads its dependencies.
    //
    // This DOES NOT make it safe to _use_ arbitrary ORT C++ APIs when
    // initializing static members, however.
    static const OrtApi* api = DefaultInit();

    if (newValue) {
      api = newValue;
    }

    return api;
  }

 private:
  // Has different definitions based on ORT_API_MANUAL_INIT
  static const OrtApi* DefaultInit() noexcept;

#ifdef ORT_API_MANUAL_INIT
  // Public APIs to set the OrtApi* to use.