luca-piccioni / OpenGL.Net

Modern OpenGL bindings for C#.
MIT License
579 stars 109 forks source link

Possible Mono - .Net Core 2.0 compatibility quirks. #107

Open mode777 opened 6 years ago

mode777 commented 6 years ago

Hey everyone,

First of all, thanks for this great project. I just managed to get the VideoCore Sample running on a Raspberry Pi 3 under .Net Core 2.0 and ran into some issues, which I was able to fix. Some might Rpi specific, but some of it seems to be related to different behaviour between mono and .net core 2.0. Maybe you will find this useful.

First of all I changed the VideoCore and HelloTriangle.VideoCore projects to target .net core 2.0. Everything compiled fine, but running it on my Rpi got me some runtime exception

String marshalling issues

Khronos.Net does string marshalling on native functions which does not work with .net core. Changing this:

[DllImport("dl")]
public static extern IntPtr dlopen([MarshalAs(UnmanagedType.LPTStr)] string filename, int flags);

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

[DllImport("dl")]
public static extern string dlerror();

to this

[DllImport("dl")]
public static extern IntPtr dlopen(string filename, int flags);

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

[DllImport("dl", EntryPoint = "dlerror")]
public static extern string dlerror();

fixed it for me.

Automatic .dll to .so replacment

Mono seems to (automatically?) replace DllImport's which end in .dll with .so. .Net Core does not seem to do this. In the file GetProcAddressGL.cs I had to replace this:

[DllImport("libEGL.dll", EntryPoint = "eglGetProcAddress")]
public static extern IntPtr GetProcAddressCore(string funcname);

with this:

[DllImport("libEGL.so", EntryPoint = "eglGetProcAddress")]
public static extern IntPtr GetProcAddressCore(string funcname);

OpenGL.Net.VideoCore does not call bcm_host_init

Again, I'm not sure if this is related to Mono vs. .Net Core 2 or a regular bug in OpenGL.Net.VideoCore but this event:

static VideoCoreWindow()
{
    // Support for RPi
    KhronosApi.EglInitializing += KhronosApi_PlatformInit_Rpi;
}

is never fired. I had to manually call Bcm.bcm_host_init(); in the VideoCoreWindow constructor.

I woud submit a pull request for this issue but I'm afraid, that it might break existing code which relies on Mono. I feel that there is further research needed.

luca-piccioni commented 5 years ago

Sorry, I completely forgot this issue. Indeed, let's see the points of this issue.

String marshalling issues

Nothing to argue, since I've no experience on .NET Core. Probably .NET Core is fix string marshaling to a single method.

Automatic .dll to .so replacement

The use of .dll extension is because EGL bindings were developed/integrated before on Windows, and later on Linux. Since I run on RPi with mono, no issues were found.

Maybe the definitive solution could be hard-coding the actual path to use, and load it dynamically using OS loader.

OpenGL.Net.VideoCore does not call bcm_host_init

Currently I ignore why the bcm_host_initfunction is not called, it should be. Or Egl.EglInitializing is not triggering, of Bcm.IsAvailable is false. I'll check it soon.