Use link_name for dynamic library loading #3101
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Problems
Dynamic library codegen generates code trying to load symbols using the name exposed in bindings instead of the overriden link name or mangled name.
Note that libloading::Library::get does not mangle the name for you
dynamic_library_name
on the builder), the symbol names used in the generated__library.get("XXX")
calls aren't the mangled link name as one might expect, but instead the bindings name. This behaviour by chance works with C-style exports, but is incorrect with mangled symbols (e.g. C++ exports) or when a user overrides the name of an item.Example
If my function in C is defined like this:
I might have something like this implemented on my Processor to lop off the prefix, since it feels redundant when the item is already namespaced by being a member of the generated dylib type.
The line in the generated from_library will then look for the wrong symbol "coolFunction"
when it should be this:
When troubleshooting I messed around with
generated_link_name_override
, and noticed that it doesn't affect that generated code at all, and also reveals the second problem mentioned above about the link_name attribute -- the attribute is added if the symbol name would differ from the canonical one -- in this case because it's overriden.Note that
generated_link_name_override
is, confusingly, passed the normal name (possibly overriden by the processor'sgenerated_name_override
), rather than the link name. So in my case even with the PR's changes I had to add the following to my Processor impl to re-add the prefix for to the symbol so that it can be found:I decided not to touch this last oddity in the PR in case I'm overlooking something, but would be happy to tack it on with go-ahead from a maintainer.
Changes in the PR
__library.get
call will use the link_name for a function or var; i.e., the same as what is generated for link_name attributes. In order of precedence, this is:I have tested and confirmed that the changes generate fully working bindings on my own windows and linux environments with a test dynamic library and binary that loads it.