0

This is a follow up question on this one.

I am using the dlopen and dlclose functions to load/unload a shared library. (They both return void*).
I am saving the dlopen handle inside a dictionary.
Every time an element is erased from the map, dlclose function should be called automatically.

This is what I have:

auto closeFunc = [](void* vp) {
  dlclose(vp);
};
using HandlePtr = std::unique_ptr<void, decltype(closeFunc)>;
std::map<std::string, HandlePtr> handles;

HandlePtr handle(dlopen(path.c_str(), RTLD_LAZY), closeFunc );
handles[nameStr] = std::move( handle );

My issue is when I want to iterate over the keys of the map (strings) and print them, it forces me to take the address:

vector<string> SharedLibrary::GetLoadedLibraries() {
    vector<string> loadedLibraries;

    for(auto& kv: handles) {
        loadedLibraries.push_back(kv.first);
    }

    return loadedLibraries;
}

Because of this it will clear my map when loadedLibraries goes out of scope.
If I don't take the reference I have a compilation error "using a deleted function".

I am kinda confuse by this. What is the proper way to retrieve the keys from the map ?

Adrian
  • 19,440
  • 34
  • 112
  • 219
  • 2
    *"Because of this it will clear my map when loadedLibraries goes out of scope"* - It won't. `loadedLibraries` holds copies of the keys. – StoryTeller - Unslander Monica May 27 '19 at 08:29
  • The loop doesn't take any addresses, references are not pointers. And as mentioned you add copies of the key to the vector. The vector is totally distinct and separate from the `handles` map. – Some programmer dude May 27 '19 at 08:30
  • But why is my closeFunc called when running this method to retrieve the keys ? That is what is weird to me :/ – Adrian May 27 '19 at 08:31
  • 2
    Probably because the example you show is not indicative of the code you actually have. Please post a [mcve]. `closeFunc` can just print to show the issue is happening. No need to pull in `libdl`. – StoryTeller - Unslander Monica May 27 '19 at 08:32
  • I updated code to show the method I call. – Adrian May 27 '19 at 08:35
  • I am only guessing here. You cannot copy a unique_ptr. So when iterating you have to take a (const) reference. Using 'for (auto pr : handles)' will copy the value type of the map and hence the compiler error of invoking copy constructor. – gast128 May 27 '19 at 08:49
  • `handles[nameStr] = std::move( handle )` doesn't compile. It requires default-constructing `HandlePtr`, which in turn requires default-constructing `decltype(closeFunc)`, which doesn't have a default constructor. Make it `handles.emplace(nameStr, std::move( handle ));` With this change, [your code appears to work](https://rextester.com/HFWY67138) for me. The one `closing` call is when the global variable `handles` is destroyed at the end of the program. To the extent there is a problem, it likely lies in the code you haven't shown. – Igor Tandetnik May 27 '19 at 14:39

0 Answers0