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

Support non-windows platforms #1

Open
forrestthewoods opened this issue Sep 1, 2019 · 1 comment
Open

Support non-windows platforms #1

forrestthewoods opened this issue Sep 1, 2019 · 1 comment

Comments

@forrestthewoods
Copy link
Owner

Would like to support platforms other than Windows. Requires at least two things.

  1. Wrap SystemLibrary methods with platform specific calls.
  2. Provide platform specific library extensions.

Platform system calls may take different parameters. Which may require updated LoadAll as well.

@futscdav
Copy link

futscdav commented Sep 10, 2020

I adapted this to my needs on Linux, which was fairly simple to do. I might change the Attributes later on, but this has been an excellent starting point. If you are interested, these changes should be sufficient to make it work under Linux (and possibly MacOS and Android too, but I have no way to test that, so I only ifdef LINUX).

Define SystemLibrary based on current OS:

    #if UNITY_STANDALONE_WIN
    static class SystemLibrary
    {
        [DllImport("kernel32", SetLastError = true, CharSet = CharSet.Unicode)]
        static public extern IntPtr LoadLibrary(string lpFileName);

        [DllImport("kernel32", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static public extern bool FreeLibrary(IntPtr hModule);

        [DllImport("kernel32")]
        static public extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);

        [DllImport("kernel32.dll")]
        static public extern uint GetLastError();
    }
    #elif UNITY_STANDALONE_LINUX
    static class SystemLibraryLinux
    {
        [DllImport("dl")]
        static public extern IntPtr dlopen(string filename, int flags);

        [DllImport("dl")]
        static public extern int dlclose(IntPtr handle);

        [DllImport("dl")]
        static public extern IntPtr dlsym(IntPtr handle, string symbol);

        [DllImport("dl")]
        static public extern string dlerror();
    }
    static class SystemLibrary
    {
        static public IntPtr LoadLibrary(string lpFileName) {
            var _ = SystemLibraryLinux.dlerror();
            var handle = SystemLibraryLinux.dlopen(lpFileName, 0x00002 | 0x00100); // RTLD_NOW | RTLD_GLOBAL
            return handle;
        }

        static public bool FreeLibrary(IntPtr hModule) {
            var success = SystemLibraryLinux.dlclose(hModule);
            return success == 0;
        }

        static public IntPtr GetProcAddress(IntPtr hModule, string procedureName) {
            var _ = SystemLibraryLinux.dlerror();
            var address = SystemLibraryLinux.dlsym(hModule, procedureName);
            return address;
        }

        static public string GetLastError() {
            var error = SystemLibraryLinux.dlerror();
            return error;
        }
    }
    #endif

Change EXT to platform based

    // Constants
    #if UNITY_STANDALONE_WIN
    const string EXT = ".dll"; // TODO: Handle different platforms
    #elif UNITY_STANDALONE_LINUX
    const string EXT = ".so";
    #endif

The only difference this way is that GetLastError() returns a string but since the LoadAll is using string.Format, it will work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants