| 36 | #define STRINGFY0(s) #s |
| 37 | |
| 38 | bool HighsExternalApi::tryLoad(const std::string& path) { |
| 39 | HighsExternalApi& inst = instance(); |
| 40 | static std::once_flag flag; |
| 41 | |
| 42 | // prevents multiple attempts to load the library |
| 43 | // ensure thread safety (multiple threads may call tryLoad simultaneously) |
| 44 | std::call_once(flag, [&]() { |
| 45 | inst.available_ = false; |
| 46 | |
| 47 | // Load library |
| 48 | #if defined(_WIN32) || defined(_WIN64) |
| 49 | const char* library_filename = "highs_extras.dll"; |
| 50 | #elif defined(__APPLE__) |
| 51 | const char* library_filename = "libhighs_extras.dylib"; |
| 52 | #else |
| 53 | const char* library_filename = "libhighs_extras.so"; |
| 54 | #endif |
| 55 | |
| 56 | bool ok = inst.library_.load(library_filename, path); |
| 57 | inst.status_ = "Extras: " + inst.library_.status(); |
| 58 | |
| 59 | if (ok) { |
| 60 | try { |
| 61 | // Check ABI compatibility |
| 62 | std::string highs_version = STRINGFY(HIGHS_VERSION_MAJOR) "." STRINGFY( |
| 63 | HIGHS_VERSION_MINOR) "." STRINGFY(HIGHS_VERSION_PATCH); |
| 64 | |
| 65 | std::string extras_version = |
| 66 | inst.library_.call<get_version_t>("HighsExtras_getVersion"); |
| 67 | |
| 68 | if (extras_version == highs_version) { |
| 69 | inst.extras_feature_info_ = inst.library_.call<get_feature_info_t>( |
| 70 | "HighsExtras_getFeatureInfo"); |
| 71 | |
| 72 | inst.library_.call<get_api_t>("HighsExtras_getApi", &inst.api_); |
| 73 | } else { |
| 74 | inst.status_ = "Extras: ABI version mismatch: expected " + |
| 75 | highs_version + ", got " + extras_version + "."; |
| 76 | ok = false; |
| 77 | } |
| 78 | } catch (const std::exception& e) { |
| 79 | inst.status_ = std::string("Extras: failed to load API: ") + e.what(); |
| 80 | ok = false; |
| 81 | } |
| 82 | |
| 83 | if (!ok) { |
| 84 | inst.unload(); |
| 85 | } |
| 86 | } |
| 87 | |
| 88 | inst.available_ = ok; |
| 89 | }); |
| 90 | |
| 91 | return inst.available_; |
| 92 | } |
| 93 | #else |
| 94 | bool HighsExternalApi::tryLoad(const std::string& path) { |
| 95 | (void)path; |
nothing calls this directly
no test coverage detected