Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interop request: Support exported symbols #19566

Open
jkotas opened this issue Aug 20, 2018 · 6 comments

Comments

Projects
None yet
4 participants
@jkotas
Copy link
Member

commented Aug 20, 2018

From @MV10 on August 19, 2018 17:5

Request: Define a new attribute which maps a managed variable to an exported symbol, exactly as we get today using [DllImport] for functions.

Right now I'm facing the need to read data (defined constants and live variables) from Windows, Linux, and OSX native libraries. At the moment I'm not sure how to accomplish the same thing in Linux and OSX (I've just started down this rabbit-hole), but it definitely feels like the type of "it just works" magic that .NET ought to handle for us, because this gets ugly fast.

This is the Win32 way (although in my case I think I can skip LoadLibrary and FreeLibrary and just use GetModuleHandle since pinvoke will have already loaded it):

https://limbioliong.wordpress.com/2011/11/11/accessing-exported-data-from-a-dll-in-managed-code/

I suppose I'll have to target each OS with #if blocks based on Runtime Identifier build constants once I figure out how it works on the other platforms.

(On a related note, I noticed in #24444 the OP asks about data and interfaces but it seems the data portion of the question was overlooked.)

Copied from original issue: dotnet/corefx#31836

@AaronRobinsonMSFT

This comment has been minimized.

Copy link
Member

commented Aug 21, 2018

@MV10 This is an interesting idea, but I think there are some serious issues with anything that needs to be marshaled. In the example in the link provided I can imagine how ints and doubles could be provided in a similar way, but strings and most other things would wind up being turned into a function - either explicitly or implicitly - so we could marshal them into managed. Alternatively we could just provide them as IntPtr, but that also seems to not be what you really want.

Could you provide an example scenario - just so we have an idea on how to think about this?

edit Also what kind of memory guarantees would you expect? If we have to marshal something it, by definition, is no longer the same as what it was marshaled from.

@AaronRobinsonMSFT AaronRobinsonMSFT added this to the Future milestone Aug 21, 2018

@AaronRobinsonMSFT

This comment has been minimized.

Copy link
Member

commented Aug 21, 2018

@MV10

This comment has been minimized.

Copy link

commented Aug 21, 2018

As a way of exploring cross-platform development, I began yet-another-wrapper for the ncurses console-output library. It exports a couple of integers that reflect the size of the terminal as LINES and COLS. My initial cut looked something like this, along with #if tomfoolery to also support the posix dlopen and dlsym equivalents:

    public static int Lines => GetInt("LINES");
    public static int Columns => GetInt("COLS");

    private static int GetInt(string symbolName)
    {
        var handle = GetModuleHandle(CursesLibName);
        var symaddr = GetProcAddress(handle, symbolName);
        return (int)Marshal.PtrToStructure(symaddr, typeof(int));
    }

Obviously it would be smart to store the module address, and maybe the symbol address (my Win32/C/C++ is rusty, can't remember if that would be safe to do without doing some Google work).

I imagined something along these lines:

[DllImport(MarshalAs=typeof(int))]
public static int Lines;

I realize this is basically read-only access, whereas others might expect two-way. I haven't really thought about it in those terms.

@MV10

This comment has been minimized.

Copy link

commented Aug 21, 2018

As an aside, I'm curious about why this discussion belongs in coreclr instead of corefx where the runtime interop code lives. When it comes to picking .net repos for new issues, my hit-miss ratio isn't great...

@jkotas

This comment has been minimized.

Copy link
Member Author

commented Aug 21, 2018

why this discussion belongs in coreclr instead of corefx where the runtime interop code lives

The runtime interop code lives in CoreCLR.

When it comes to picking .net repos for new issues, my hit-miss ratio isn't great...

No worries.

@jack-pappas

This comment has been minimized.

Copy link
Contributor

commented Aug 25, 2018

This would be a useful feature for HDF.PInvoke. The native HDF5 C library it wraps exports values representing certain default types (akin to .NET's RuntimeTypeHandle), so HDF.PInvoke needs to implement some platform-specific logic there for getting the values:
https://github.com/HDFGroup/HDF.PInvoke/blob/90b1c76e99659d47e665a3079bc9f21c48122708/HDF5/H5DLLImporter.cs

That platform-specific logic could go away if [DllImport] supported importing values in addition to functions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.