What exactly is happening with "plugins" folder?

I have two custom OPs – CPlusPlusDATs (macOS).
If I don’t place them in “plugins” folder next to the project file, both plugins work well – I can load them into TouchDesigner together.
However, when I place both of them in the “plugins” folder, one is causing a crash when I try to instantiate it in TD.

The crash itself does not relate to TouchDesigner, but is a protobuf problem:

[libprotobuf ERROR google/protobuf/descriptor_database.cc:58] File already exists in database: content-meta-info.proto
[libprotobuf FATAL google/protobuf/descriptor.cc:1358] CHECK failed: GeneratedDatabase()->Add(encoded_file_descriptor, size): 
libc++abi.dylib: terminating with uncaught exception of type google::protobuf::FatalException: CHECK failed: GeneratedDatabase()->Add(encoded_file_descriptor, size): 

From which I learn that, internally, protobuf tried to add same file descriptor to the database twice. Since protobuf does it somewhere at a startup (when static variables initialize), I tend to believe that somehow, this code gets executed when plugin being loaded from the “plugins” folder and then the second time when the plugin is instantiated and this is causing the crash.
Hence, I’d like to understand more on the process of loading plugins by TouchDesigner.
(For example, can it be that “dlopen” call called twice? Or when exactly is it called?)

PS. In my debugger I see this sequence of calls:

plugin1 - FillDATPluginInfo(..)
plugin2 - FillDATPluginInfo(..)
<try instantiate plugin2>
->! protobuf crash !<-

Yes, the plugin will be loaded twice. Maybe this is wrong, or we could add an option in FillDATPluginInfo() where you tell me not to unload it. Basically we load it to get information about the plugin so we can fill the OP Create Dialog, but then unload it. We’ll load it again if you decide you really want to create a node of that type.

Ah I see… Thanks Malcolm.
Then It’s never really unloaded, from the man to dlclose:

Prior to Mac OS X 10.5, only bundles could be unloaded.  Starting in Mac
OS X 10.5, dynamic libraries may also be unloaded.  There are a couple of
cases in which a dynamic library will never be unloaded: 1) the main exe-
cutable links against it, 2) An API that does not supoort unloading (e.g.
NSAddImage()) was used to load it or some other dynnamic library that
depends on it, 3) the dynamic library is in dyld's shared cache.

it seems that I’m getting case #3. According to the posix standard, dlclose is not required to actually unload the library (pubs.opengroup.org/onlinepubs/00 … close.html), which makes me think – if plugin is loaded to read information about it and then unloaded again (but the system never does that), does it really optimizes anything even when the plugin never used?..
As a result, one might run into weird behavior as described in previous post, where using “plugins” folder isn’t feasible.
I think, if you really need to unload (I guess because you can’t be 100% sure whether the system will unload it or not eventually), then having an option in FillDATPluginInfo() to indicate not to unload would be helpful.

What’s strange though is if it’s never unloaded, then calling dlopen another time should just give a reference to the existing loaded module, and not re-call the static initialization of the plugin