Commit 5aa3062d authored by Martin Finkel's avatar Martin Finkel

WIP. Currently trying to marshal media discoverers back to managed code.

parent 53e88fd6
......@@ -77,5 +77,23 @@ namespace Bindings.Tests
Debug.WriteLine(audioOutputDevice.Device);
}
}
[Test]
public void EqualityTests()
{
var instance1 = new Instance(0, null);
var instance2 = new Instance(0, null);
Assert.True(instance1 != instance2);
}
[Test]
public void Categories()
{
var instance = new Instance(0, null);
//var md1 = instance.MediaDiscoverers(MediaDiscovererCategory.Devices);
var md2 = instance.MediaDiscoverers(MediaDiscovererCategory.Lan);
//var md3 = instance.MediaDiscoverers(MediaDiscovererCategory.Localdirs);
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
using Sample.Manual;
namespace libvlcsharp
{
......@@ -87,7 +89,17 @@ namespace libvlcsharp
[SuppressUnmanagedCodeSecurity]
[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_audio_output_device_list_release")]
internal static extern void LibVLCAudioOutputDeviceListRelease(IntPtr list);
internal static extern void LibVLCAudioOutputDeviceListRelease(IntPtr list);
[SuppressUnmanagedCodeSecurity]
[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_discoverer_list_get")]
internal static extern IntPtr LibVLCMediaDiscovererListGet(IntPtr instance, MediaDiscovererCategory category, ref IntPtr pppServices);
[SuppressUnmanagedCodeSecurity]
[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_discoverer_list_release")]
internal static extern void LibVLCMediaDiscovererListRelease(IntPtr ppServices, ulong count);
}
public IntPtr NativeReference { get; protected set; }
......@@ -261,11 +273,15 @@ namespace libvlcsharp
/// <para>complete (causing a deadlock if called from within the callback).</para>
/// <para>LibVLC 2.1.0 or later</para>
/// </remarks>
public void UnsetLog()
public void UnsetLog()
{
Internal.LibVLCLogUnset(NativeReference);
}
public void SetLog()
{
}
//TODO: void logSet(LogCb&& logCb)
/// <summary>Sets up logging to a file.</summary>
......@@ -385,9 +401,73 @@ namespace libvlcsharp
s => AudioOutputDevice.__CreateInstance(s),
device => device.Next, Internal.LibVLCAudioOutputDeviceListRelease);
}
//https://www.videolan.org/developers/vlc/doc/doxygen/html/group__libvlc__media__discoverer.html#ga9a4676e452daa2fd4b5eb371542afc29
// code inspired from https://code.videolan.org/videolan/libvlcpp/blob/master/vlcpp/Instance.hpp
// https://stackoverflow.com/questions/13457375/how-do-i-call-an-unmanaged-function-that-has-a-char-as-out-parameter-from-c
// https://stackoverflow.com/questions/11131676/how-do-i-marshall-a-pointer-to-a-pointer-of-an-array-of-structures
public IEnumerable<MediaDiscovererDescription> MediaDiscoverers(MediaDiscovererCategory category)
{
var arrayResultPtr = IntPtr.Zero;
var count = Internal.LibVLCMediaDiscovererListGet(NativeReference, category, ref arrayResultPtr).ToInt32();
//var count = Internal.LibVLCMediaDiscovererListGet(NativeReference, category, out var arrayResultPtr).ToInt32();
if (count == 0) return Enumerable.Empty<MediaDiscovererDescription>();
var size = Marshal.SizeOf(typeof(MediaDiscovererDescription.Internal));
var mediaDiscovererDescription = new List<MediaDiscovererDescription>();
for (var i = 0; i < count; i++)
{
var s = (MediaDiscovererDescription.Internal) Marshal.PtrToStructure(
new IntPtr(arrayResultPtr.ToInt32() + (size * i)), typeof(MediaDiscovererDescription.Internal));
var mdd = MediaDiscovererDescription.__CreateInstance(s);
Debug.WriteLine(mdd.Longname);
Debug.WriteLine(mdd.Name);
mediaDiscovererDescription.Add(mdd);
}
return mediaDiscovererDescription;
}
/// <summary>Get media discoverer services by category</summary>
/// <param name="p_inst">libvlc instance</param>
/// <param name="i_cat">category of services to fetch</param>
/// <param name="ppp_services">
/// <para>address to store an allocated array of media discoverer</para>
/// <para>services (must be freed with libvlc_media_discoverer_list_release() by</para>
/// <para>the caller) [OUT]</para>
/// </param>
/// <returns>the number of media discoverer services (0 on error)</returns>
/// <remarks>LibVLC 3.0.0 and later.</remarks>
//private ulong LibvlcMediaDiscovererListGet(global::libvlcsharp.Instance p_inst, global::libvlcsharp.MediaDiscovererCategory i_cat, global::libvlcsharp.MediaDiscovererDescription ppp_services)
//{
// var __arg0 = ReferenceEquals(p_inst, null) ? global::System.IntPtr.Zero : p_inst.NativeReference;
// var __arg2 = ReferenceEquals(ppp_services, null) ? global::System.IntPtr.Zero : ppp_services.NativeReference;
// var __ret = __Internal.LibvlcMediaDiscovererListGet(__arg0, i_cat, __arg2);
// return __ret;
//}
/// <summary>Release an array of media discoverer services</summary>
/// <param name="ppServices">array to release</param>
/// <param name="count">number of elements in the array</param>
/// <remarks>
/// <para>LibVLC 3.0.0 and later.</para>
/// <para>libvlc_media_discoverer_list_get()</para>
/// </remarks>
private void ReleaseMediaDiscovererList(MediaDiscovererDescription ppServices, ulong count)
{
Internal.LibVLCMediaDiscovererListRelease(ppServices.NativeReference, count);
}
public void SetDialogHandlers()
{
}
public void SetExistHandler(Action cb)
{
//Internal.LibVLCSetExitHandler();
}
}
}
\ No newline at end of file
......@@ -865,6 +865,6 @@ namespace libvlcsharp
namespace Delegates
{
[SuppressUnmanagedCodeSecurity, UnmanagedFunctionPointer(global::System.Runtime.InteropServices.CallingConvention.Cdecl)]
public unsafe delegate void Action_IntPtr(global::System.IntPtr _0);
public unsafe delegate void Action_IntPtr();
}
}
......@@ -7,9 +7,12 @@
using System;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
using Sample.Manual;
namespace libvlcsharp
{
/// <summary>Category of a media discoverer</summary>
/// <remarks>libvlc_media_discoverer_list_get()</remarks>
public enum MediaDiscovererCategory
......@@ -36,6 +39,8 @@ namespace libvlcsharp
/// </summary>
public unsafe partial class MediaDiscoverer
{
[StructLayout(LayoutKind.Explicit, Size = 0)]
public partial struct __Internal
{
......@@ -83,27 +88,28 @@ namespace libvlcsharp
/// <summary>Media discoverer description</summary>
/// <remarks>libvlc_media_discoverer_list_get()</remarks>
public unsafe partial class MediaDiscovererDescription : IDisposable
public unsafe partial class MediaDiscovererDescription //: IDisposable
{
[StructLayout(LayoutKind.Explicit, Size = 24)]
public partial struct __Internal
[StructLayout(LayoutKind.Sequential)]
public struct Internal
{
[FieldOffset(0)]
internal global::System.IntPtr psz_name;
//[FieldOffset(0)]
internal IntPtr psz_name;
[FieldOffset(8)]
internal global::System.IntPtr psz_longname;
//[FieldOffset(8)]
internal IntPtr psz_longname;
[FieldOffset(16)]
internal global::libvlcsharp.MediaDiscovererCategory i_cat;
//[FieldOffset(16)]
//internal IntPtr i_cat;
internal int i_cat;
[SuppressUnmanagedCodeSecurity]
[DllImport("libvlc", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
EntryPoint="??0libvlc_media_discoverer_description_t@@QEAA@AEBU0@@Z")]
internal static extern global::System.IntPtr cctor(global::System.IntPtr instance, global::System.IntPtr _0);
//[SuppressUnmanagedCodeSecurity]
//[DllImport("libvlc", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
// EntryPoint="??0libvlc_media_discoverer_description_t@@QEAA@AEBU0@@Z")]
//internal static extern global::System.IntPtr cctor(global::System.IntPtr instance, global::System.IntPtr _0);
}
public global::System.IntPtr __Instance { get; protected set; }
public IntPtr NativeReference { get; protected set; }
protected int __PointerAdjustment;
internal static readonly global::System.Collections.Concurrent.ConcurrentDictionary<IntPtr, global::libvlcsharp.MediaDiscovererDescription> NativeToManagedMap = new global::System.Collections.Concurrent.ConcurrentDictionary<IntPtr, global::libvlcsharp.MediaDiscovererDescription>();
......@@ -116,45 +122,45 @@ namespace libvlcsharp
return new global::libvlcsharp.MediaDiscovererDescription(native.ToPointer(), skipVTables);
}
internal static global::libvlcsharp.MediaDiscovererDescription __CreateInstance(global::libvlcsharp.MediaDiscovererDescription.__Internal native, bool skipVTables = false)
internal static global::libvlcsharp.MediaDiscovererDescription __CreateInstance(global::libvlcsharp.MediaDiscovererDescription.Internal native, bool skipVTables = false)
{
return new global::libvlcsharp.MediaDiscovererDescription(native, skipVTables);
}
private static void* __CopyValue(global::libvlcsharp.MediaDiscovererDescription.__Internal native)
private static void* __CopyValue(global::libvlcsharp.MediaDiscovererDescription.Internal native)
{
var ret = Marshal.AllocHGlobal(sizeof(global::libvlcsharp.MediaDiscovererDescription.__Internal));
*(global::libvlcsharp.MediaDiscovererDescription.__Internal*) ret = native;
var ret = Marshal.AllocHGlobal(sizeof(global::libvlcsharp.MediaDiscovererDescription.Internal));
*(global::libvlcsharp.MediaDiscovererDescription.Internal*) ret = native;
return ret.ToPointer();
}
private MediaDiscovererDescription(global::libvlcsharp.MediaDiscovererDescription.__Internal native, bool skipVTables = false)
private MediaDiscovererDescription(global::libvlcsharp.MediaDiscovererDescription.Internal native, bool skipVTables = false)
: this(__CopyValue(native), skipVTables)
{
__ownsNativeInstance = true;
NativeToManagedMap[__Instance] = this;
NativeToManagedMap[NativeReference] = this;
}
protected MediaDiscovererDescription(void* native, bool skipVTables = false)
{
if (native == null)
return;
__Instance = new global::System.IntPtr(native);
NativeReference = new global::System.IntPtr(native);
}
public MediaDiscovererDescription()
{
__Instance = Marshal.AllocHGlobal(sizeof(global::libvlcsharp.MediaDiscovererDescription.__Internal));
NativeReference = Marshal.AllocHGlobal(sizeof(global::libvlcsharp.MediaDiscovererDescription.Internal));
__ownsNativeInstance = true;
NativeToManagedMap[__Instance] = this;
NativeToManagedMap[NativeReference] = this;
}
public MediaDiscovererDescription(global::libvlcsharp.MediaDiscovererDescription _0)
{
__Instance = Marshal.AllocHGlobal(sizeof(global::libvlcsharp.MediaDiscovererDescription.__Internal));
NativeReference = Marshal.AllocHGlobal(sizeof(global::libvlcsharp.MediaDiscovererDescription.Internal));
__ownsNativeInstance = true;
NativeToManagedMap[__Instance] = this;
*((global::libvlcsharp.MediaDiscovererDescription.__Internal*) __Instance) = *((global::libvlcsharp.MediaDiscovererDescription.__Internal*) _0.__Instance);
NativeToManagedMap[NativeReference] = this;
*((global::libvlcsharp.MediaDiscovererDescription.Internal*) NativeReference) = *((global::libvlcsharp.MediaDiscovererDescription.Internal*) _0.NativeReference);
}
public void Dispose()
......@@ -164,53 +170,34 @@ namespace libvlcsharp
public virtual void Dispose(bool disposing)
{
if (__Instance == IntPtr.Zero)
if (NativeReference == IntPtr.Zero)
return;
global::libvlcsharp.MediaDiscovererDescription __dummy;
NativeToManagedMap.TryRemove(__Instance, out __dummy);
NativeToManagedMap.TryRemove(NativeReference, out __dummy);
if (__ownsNativeInstance)
Marshal.FreeHGlobal(__Instance);
__Instance = IntPtr.Zero;
Marshal.FreeHGlobal(NativeReference);
NativeReference = IntPtr.Zero;
}
public sbyte* PszName
public string Name
{
get
{
return (sbyte*) ((global::libvlcsharp.MediaDiscovererDescription.__Internal*) __Instance)->psz_name;
}
set
{
((global::libvlcsharp.MediaDiscovererDescription.__Internal*) __Instance)->psz_name = (global::System.IntPtr) value;
//Encoding.UTF8.GetBytes(((Internal*)NativeReference)->psz_name))
var r2 = (string)Utf8StringMarshaler.GetInstance().MarshalNativeToManaged(((Internal*)NativeReference)->psz_name);
//var r2 = Marshal.PtrToStringAuto(((Internal*)NativeReference)->psz_name);
var r1 = Marshal.PtrToStringAnsi(((Internal*)NativeReference)->psz_name);
return r1;
//var r4 = Marshal.PtrToStringUni(((Internal*)NativeReference)->psz_name);
//return r3;
}
}
//=> (string)Utf8StringMarshaler.GetInstance().MarshalNativeToManaged(((Internal*)NativeReference)->psz_name);
public string Longname => (string)Utf8StringMarshaler.GetInstance().MarshalNativeToManaged(((Internal*)NativeReference)->psz_longname);
//public string Longname => Marshal.PtrToStringAnsi(((Internal*)NativeReference)->psz_longname);
public sbyte* PszLongname
{
get
{
return (sbyte*) ((global::libvlcsharp.MediaDiscovererDescription.__Internal*) __Instance)->psz_longname;
}
set
{
((global::libvlcsharp.MediaDiscovererDescription.__Internal*) __Instance)->psz_longname = (global::System.IntPtr) value;
}
}
public global::libvlcsharp.MediaDiscovererCategory ICat
{
get
{
return ((global::libvlcsharp.MediaDiscovererDescription.__Internal*) __Instance)->i_cat;
}
set
{
((global::libvlcsharp.MediaDiscovererDescription.__Internal*) __Instance)->i_cat = value;
}
}
//public MediaDiscovererCategory Category => (MediaDiscovererCategory) ((Internal*) NativeReference)->i_cat;
}
public unsafe partial class libvlc_media_discoverer
......@@ -247,15 +234,6 @@ namespace libvlcsharp
EntryPoint="libvlc_media_discoverer_is_running")]
internal static extern int LibvlcMediaDiscovererIsRunning(global::System.IntPtr p_mdis);
[SuppressUnmanagedCodeSecurity]
[DllImport("libvlc", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
EntryPoint="libvlc_media_discoverer_list_get")]
internal static extern ulong LibvlcMediaDiscovererListGet(global::System.IntPtr p_inst, global::libvlcsharp.MediaDiscovererCategory i_cat, global::System.IntPtr ppp_services);
[SuppressUnmanagedCodeSecurity]
[DllImport("libvlc", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
EntryPoint="libvlc_media_discoverer_list_release")]
internal static extern void LibvlcMediaDiscovererListRelease(global::System.IntPtr pp_services, ulong i_count);
}
/// <summary>Create a media discoverer object by name.</summary>
......@@ -351,35 +329,6 @@ namespace libvlcsharp
return __ret;
}
/// <summary>Get media discoverer services by category</summary>
/// <param name="p_inst">libvlc instance</param>
/// <param name="i_cat">category of services to fetch</param>
/// <param name="ppp_services">
/// <para>address to store an allocated array of media discoverer</para>
/// <para>services (must be freed with libvlc_media_discoverer_list_release() by</para>
/// <para>the caller) [OUT]</para>
/// </param>
/// <returns>the number of media discoverer services (0 on error)</returns>
/// <remarks>LibVLC 3.0.0 and later.</remarks>
public static ulong LibvlcMediaDiscovererListGet(global::libvlcsharp.Instance p_inst, global::libvlcsharp.MediaDiscovererCategory i_cat, global::libvlcsharp.MediaDiscovererDescription ppp_services)
{
var __arg0 = ReferenceEquals(p_inst, null) ? global::System.IntPtr.Zero : p_inst.NativeReference;
var __arg2 = ReferenceEquals(ppp_services, null) ? global::System.IntPtr.Zero : ppp_services.__Instance;
var __ret = __Internal.LibvlcMediaDiscovererListGet(__arg0, i_cat, __arg2);
return __ret;
}
/// <summary>Release an array of media discoverer services</summary>
/// <param name="pp_services">array to release</param>
/// <param name="i_count">number of elements in the array</param>
/// <remarks>
/// <para>LibVLC 3.0.0 and later.</para>
/// <para>libvlc_media_discoverer_list_get()</para>
/// </remarks>
public static void LibvlcMediaDiscovererListRelease(global::libvlcsharp.MediaDiscovererDescription pp_services, ulong i_count)
{
var __arg0 = ReferenceEquals(pp_services, null) ? global::System.IntPtr.Zero : pp_services.__Instance;
__Internal.LibvlcMediaDiscovererListRelease(__arg0, i_count);
}
}
}
......@@ -930,7 +930,7 @@ namespace libvlcsharp
__Instance = IntPtr.Zero;
}
//public string Name => Marshal.PtrToStringAnsi(((Internal *) __Instance)->psz_name);
//public string Name => Marshal.PtrToStringAnsi(((Internal *) NativeReference)->psz_name);
public string Name => (string)Utf8StringMarshaler.GetInstance().MarshalNativeToManaged(((Internal *) __Instance)->psz_name);
public string Description => (string)Utf8StringMarshaler.GetInstance().MarshalNativeToManaged(((Internal*)__Instance)->psz_description);
......
......@@ -28,7 +28,7 @@
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<PlatformTarget>x86</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment