6
6
#include < algorithm>
7
7
#include < cassert>
8
8
#include < charconv>
9
+ #include < iostream>
9
10
#include < list>
10
11
#include < memory>
11
12
#include < mutex>
@@ -35,7 +36,7 @@ void check_abi_version(uint64_t abi_version) {
35
36
if (abi_version != ALPAQA_DL_ABI_VERSION) {
36
37
auto prob_version = format_abi_version (abi_version);
37
38
auto alpaqa_version = format_abi_version (ALPAQA_DL_ABI_VERSION);
38
- throw std::runtime_error (
39
+ throw invalid_abi_error (
39
40
" alpaqa::dl::DLProblem::DLProblem: "
40
41
" Incompatible problem definition (problem ABI version 0x" +
41
42
prob_version + " , this version of alpaqa supports 0x" +
@@ -62,8 +63,8 @@ std::shared_ptr<void> load_lib(const std::filesystem::path &so_filename) {
62
63
assert (!so_filename.empty ());
63
64
void *h = LoadLibraryW (so_filename.c_str ());
64
65
if (!h)
65
- throw std::runtime_error (" Unable to load \" " + so_filename.string () +
66
- " \" : " + get_last_error_msg ().get ());
66
+ throw function_load_error (" Unable to load \" " + so_filename.string () +
67
+ " \" : " + get_last_error_msg ().get ());
67
68
#if ALPAQA_NO_DLCLOSE
68
69
return std::shared_ptr<void >{h, +[](void *) {}};
69
70
#else
@@ -77,8 +78,8 @@ F *load_func(void *handle, const std::string &name) {
77
78
assert (handle);
78
79
auto *h = GetProcAddress (static_cast <HMODULE>(handle), name.c_str ());
79
80
if (!h)
80
- throw std::runtime_error (" Unable to load function '" + name +
81
- " ': " + get_last_error_msg ().get ());
81
+ throw function_load_error (" Unable to load function '" + name +
82
+ " ': " + get_last_error_msg ().get ());
82
83
// We can only hope that the user got the signature right ...
83
84
return reinterpret_cast <F *>(h);
84
85
}
@@ -88,7 +89,7 @@ std::shared_ptr<void> load_lib(const std::filesystem::path &so_filename) {
88
89
::dlerror ();
89
90
void *h = ::dlopen (so_filename.c_str (), RTLD_LOCAL | RTLD_NOW);
90
91
if (auto *err = ::dlerror ())
91
- throw std::runtime_error (err);
92
+ throw function_load_error (err);
92
93
#if ALPAQA_NO_DLCLOSE
93
94
return std::shared_ptr<void >{h, +[](void *) {}};
94
95
#else
@@ -102,8 +103,8 @@ F *load_func(void *handle, const std::string &name) {
102
103
::dlerror ();
103
104
auto *h = ::dlsym (handle, name.c_str ());
104
105
if (auto *err = ::dlerror ())
105
- throw std::runtime_error (" Unable to load function '" + name +
106
- " ': " + err);
106
+ throw function_load_error (" Unable to load function '" + name +
107
+ " ': " + err);
107
108
// We can only hope that the user got the signature right ...
108
109
return reinterpret_cast <F *>(h);
109
110
}
@@ -205,7 +206,17 @@ DLProblem::DLProblem(const std::filesystem::path &so_filename,
205
206
: BoxConstrProblem{0 , 0 } {
206
207
if (so_filename.empty ())
207
208
throw std::invalid_argument (" Invalid problem filename" );
208
- handle = load_lib (so_filename);
209
+ handle = load_lib (so_filename);
210
+ try {
211
+ auto *version_func = load_func<alpaqa_dl_abi_version_t (void )>(
212
+ handle.get (), function_name + " _version" );
213
+ check_abi_version (version_func ());
214
+ } catch (const function_load_error &) {
215
+ std::cerr << " Warning: problem " << so_filename
216
+ << " does not provide a function to query the ABI version, "
217
+ " alpaqa_dl_abi_version_t "
218
+ << function_name << " _version(void)\n " ;
219
+ }
209
220
auto *register_func = load_func<problem_register_t (alpaqa_register_arg_t )>(
210
221
handle.get (), function_name);
211
222
auto r = register_func (user_param);
@@ -342,6 +353,16 @@ DLControlProblem::DLControlProblem(const std::filesystem::path &so_filename,
342
353
if (so_filename.empty ())
343
354
throw std::invalid_argument (" Invalid problem filename" );
344
355
handle = load_lib (so_filename);
356
+ try {
357
+ auto *version_func = load_func<alpaqa_dl_abi_version_t (void )>(
358
+ handle.get (), function_name + " _version" );
359
+ check_abi_version (version_func ());
360
+ } catch (const function_load_error &) {
361
+ std::cerr << " Warning: problem " << so_filename
362
+ << " does not provide a function to query the ABI version, "
363
+ " alpaqa_dl_abi_version_t "
364
+ << function_name << " _version(void)\n " ;
365
+ }
345
366
auto *register_func =
346
367
load_func<control_problem_register_t (alpaqa_register_arg_t )>(
347
368
handle.get (), function_name);
0 commit comments