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 variable symbols #10929

Closed
jkotas opened this issue Aug 20, 2018 · 7 comments
Closed

Interop request: Support exported variable symbols #10929

jkotas opened this issue Aug 20, 2018 · 7 comments

Comments

@jkotas
Copy link
Member

jkotas 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 dotnet/coreclr#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
Copy link
Member

AaronRobinsonMSFT 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
Copy link
Member

cc @jeffschwMSFT

@MV10
Copy link

MV10 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
Copy link

MV10 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
Copy link
Member Author

jkotas 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
Copy link
Contributor

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.

@msftgits msftgits transferred this issue from dotnet/coreclr Jan 31, 2020
@msftgits msftgits added this to the Future milestone Jan 31, 2020
@jkotas
Copy link
Member Author

jkotas commented Apr 16, 2020

This can be done in platform neutral way using System.Runtime.InteropServices.NativeLibrary APIs introduced in .NET Core 3.0.

https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.nativelibrary?view=netcore-3.1

@jkotas jkotas closed this as completed Apr 16, 2020
@jkotas jkotas changed the title Interop request: Support exported symbols Interop request: Support exported variable symbols Apr 16, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 15, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants