Avatar of Michael Paravicini
Michael Paravicini
Flag for Chile asked on

Calling unamanged function which takes a pointer to pointer parameter

I am trying to call  a function in C from my .Net Core application. The C function comes from libmpv render.h and the head looks like this:
   
int mpv_render_context_create(mpv_render_context **res, mpv_handle *mpv, mpv_render_param *params);

Open in new window

The problem is, that I have no clue how to call the function from C#.
First of all I have declared the MpvRenderParam struct as follows in C#:
   
[StructLayout(LayoutKind.Sequential)]
public unsafe struct MpvRenderParam
{
    public MpvRenderParamType Type;
    public void* Data;
}

Open in new window


Previously I have defined the Data field to be of type
IntPtr

Open in new window

but in my opinion it makes more sense when it can be an all purpose pointer, so it matches the definition of the C Library.

Following is the MpvRenderParamType enum:

    public enum MpvRenderParamType
    {
        Invalid = 0,
        ApiType = 1,
        InitParams = 2,
        Fbo = 3,
        FlipY = 4,
        Depth = 5,
        IccProfile = 6,
        AmbientLight = 7,
        X11Display = 8,
        WlDisplay = 9,
        AdvancedControl = 10,
        NextFrameInfo = 11,
        BlockForTargetTime = 12,
        SkipRendering = 13,
        DrmDisplay = 14,
        DrmDrawSurfaceSize = 15,
        DrmDisplayV2 = 15
    }

Open in new window


The actual problem


Now I have explained all the data types that were transcribed to C# but the problem still lies in creating the correct definition of the mpv_render_context_create and calling it.
First I tried to define the method like this:
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int mpv_render_context_create([Out] out IntPtr renderContext, IntPtr mpvHandle,
        MpvRenderParam[] parameters);

Open in new window


And I called it with:
var ptr = IntPtr.Zero;
var apiTypePtr = Marshal.StringToHGlobalAuto("opengl");
var i = mpv_render_context_create(out ptr, _mpvHandle, new []
{
    new MpvRenderParam(MpvRenderParamType.ApiType, apiTypePtr),
    new MpvRenderParam(MpvRenderParamType.Invalid, IntPtr.Zero
});

Open in new window


I also tried changing the first parameter to be a ref or IntPtr but no matter what combination of parameter type and calling it, I always got the same exception:
Exception thrown at 0x0000000055C73D60 (mpv-1.dll) in Otchi.App.exe: 0xC0000005: Access violation reading location 0x0000000000000010.
My last attempt was going into the unsafe part of C# and declaring the method like this:
[DllImport(LibName, CallingConvention = CallingConvention.Cdecl)]
private static extern unsafe int mpv_render_context_create(IntPtr* renderContext, IntPtr mpvHandle,
    MpvRenderParam[] parameters);

Open in new window


And calling it with the following piece of code:
IntPtr ptr;
var test = GCHandle.Alloc("opengl");
var test2 = GCHandle.ToIntPtr(test);
var apiTypePtr = Marshal.StringToHGlobalAuto("opengl");
var i = mpv_render_context_create(&ptr, _mpvHandle, new []
{
    new MpvRenderParam{Type = MpvRenderParamType.ApiType, Data = &apiTypePtr},

    new MpvRenderParam{Type = MpvRenderParamType.Invalid, Data = null}
});

Open in new window


No matter what I tried, I always get the same exception. How can I call the mpv_render_context_create without it throwing an AccessViolationException?
C.NET ProgrammingC#* dll* PInvoke

Avatar of undefined
Last Comment
Eduard Ghergu

8/22/2022 - Mon
Eduard Ghergu

Hi!
Can you have a look at the following sample:
https://github.com/mpv-player/mpv-examples/tree/master/libmpv/csharp
Michael Paravicini

ASKER
Thanks for your reply, however, in the example they use the "wid" approach, where they just embed the video. This is not what i'm looking for, I want to render the video myself into a SharpGL context. I have taken many of the DllImports from the example you have provided, however the method I am having trouble with, is not part of the examples.
ASKER CERTIFIED SOLUTION
Eduard Ghergu

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
GET A PERSONALIZED SOLUTION
Ask your own question & get feedback from real experts
Find out why thousands trust the EE community with their toughest problems.
Michael Paravicini

ASKER
thank you so much.... Cheers Michael
Experts Exchange has (a) saved my job multiple times, (b) saved me hours, days, and even weeks of work, and often (c) makes me look like a superhero! This place is MAGIC!
Walt Forbes
Eduard Ghergu

Hi!
My pleasure! Please, let me know if you need more help.