Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc
Commits
77aa5b9e
Commit
77aa5b9e
authored
Oct 21, 2007
by
Rémi Denis-Courmont
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Switch CIL bindings to libvlc API
parent
c39f7535
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
177 additions
and
455 deletions
+177
-455
bindings/cil/Makefile
bindings/cil/Makefile
+3
-3
bindings/cil/exception.cs
bindings/cil/exception.cs
+40
-78
bindings/cil/libvlc.cs
bindings/cil/libvlc.cs
+55
-186
bindings/cil/marshal.cs
bindings/cil/marshal.cs
+2
-169
bindings/cil/testvlc.cs
bindings/cil/testvlc.cs
+2
-19
bindings/cil/ustring.cs
bindings/cil/ustring.cs
+75
-0
No files found.
bindings/cil/Makefile
View file @
77aa5b9e
CS
=
gmcs
CS
=
gmcs
-codepage
:utf8
CSFLAGS
=
TARGETS
=
VideoLAN.VLC.Control.dll testvlc.exe
...
...
@@ -6,9 +6,9 @@ TARGETS = VideoLAN.VLC.Control.dll testvlc.exe
all
:
$(TARGETS)
clean
:
rm
-f
--
$(TARGETS)
*
.netmodule
rm
-f
--
$(TARGETS)
*
.netmodule
*
~
VideoLAN.VLC.Control.dll
:
marshal.cs
libvlc.cs exception
.cs
VideoLAN.VLC.Control.dll
:
marshal.cs
ustring.cs exception.cs libvlc
.cs
testvlc.exe
:
testvlc.cs VideoLAN.VLC.Control.dll
%.netmodule
:
%.cs Makefile
...
...
bindings/cil/exception.cs
View file @
77aa5b9e
...
...
@@ -22,111 +22,73 @@
**********************************************************************/
using
System
;
using
System.Runtime.InteropServices
;
namespace
VideoLAN.VLC
namespace
VideoLAN.
Lib
VLC
{
/**
*
Base class for managed
LibVLC exceptions
*
VLCException: managed base class for
LibVLC exceptions
*/
public
class
Media
Exception
:
Exception
public
class
VLC
Exception
:
Exception
{
public
Media
Exception
()
public
VLC
Exception
()
{
}
public
Media
Exception
(
string
message
)
public
VLC
Exception
(
string
message
)
:
base
(
message
)
{
}
public
Media
Exception
(
string
message
,
Exception
inner
)
public
VLC
Exception
(
string
message
,
Exception
inner
)
:
base
(
message
,
inner
)
{
}
};
public
class
PositionKeyNotSupportedException
:
MediaException
{
public
PositionKeyNotSupportedException
()
{
}
public
PositionKeyNotSupportedException
(
string
message
)
:
base
(
message
)
{
}
public
PositionKeyNotSupportedException
(
string
message
,
Exception
inner
)
:
base
(
message
,
inner
)
{
}
};
public
class
PositionOriginNotSupportedException
:
MediaException
{
public
PositionOriginNotSupportedException
()
{
}
public
PositionOriginNotSupportedException
(
string
message
)
:
base
(
message
)
{
}
public
PositionOriginNotSupportedException
(
string
message
,
Exception
inner
)
:
base
(
message
,
inner
)
{
}
};
public
class
InvalidPositionException
:
MediaException
{
public
InvalidPositionException
()
/**
* libvlc_exception_t: structure for unmanaged LibVLC exceptions
*/
[
StructLayout
(
LayoutKind
.
Sequential
)]
internal
sealed
class
NativeException
:
IDisposable
{
}
int
raised
;
int
code
;
IntPtr
message
;
public
InvalidPositionException
(
string
message
)
:
base
(
message
)
{
}
[
DllImport
(
"libvlc-control.dll"
,
EntryPoint
=
"libvlc_exception_init"
)]
static
extern
void
Init
(
NativeException
e
);
[
DllImport
(
"libvlc-control.dll"
,
EntryPoint
=
"libvlc_exception_clear"
)]
static
extern
void
Clear
(
NativeException
e
);
/*[DllImport ("libvlc-control.dll",
EntryPoint="libvlc_exception_raised")]
static extern int Raised (NativeException e);*/
[
DllImport
(
"libvlc-control.dll"
,
EntryPoint
=
"libvlc_exception_get_message"
)]
static
extern
IntPtr
GetMessage
(
NativeException
e
);
public
InvalidPositionException
(
string
message
,
Exception
inner
)
:
base
(
message
,
inner
)
public
NativeException
()
{
Init
(
this
);
}
};
public
class
PlaylistException
:
MediaException
public
void
Raise
()
{
public
PlaylistException
()
try
{
string
msg
=
U8String
.
FromNative
(
GetMessage
(
this
));
if
(
msg
!=
null
)
throw
new
VLCException
(
msg
);
}
public
PlaylistException
(
string
message
)
:
base
(
message
)
finally
{
Clear
(
this
);
}
public
PlaylistException
(
string
message
,
Exception
inner
)
:
base
(
message
,
inner
)
{
}
};
public
class
InternalException
:
MediaException
{
public
InternalException
()
{
}
public
InternalException
(
string
message
)
:
base
(
message
)
{
}
public
InternalException
(
string
message
,
Exception
inner
)
:
base
(
message
,
inner
)
public
void
Dispose
()
{
Clear
(
this
);
}
};
};
bindings/cil/libvlc.cs
View file @
77aa5b9e
...
...
@@ -24,225 +24,94 @@
using
System
;
using
System.Runtime.InteropServices
;
namespace
VideoLAN.VLC
namespace
VideoLAN.
Lib
VLC
{
public
class
MediaControl
:
IDisposable
{
/**
* Possible player status
*/
enum
PlayerStatus
/** Safe handle for unmanaged LibVLC instance pointer */
internal
sealed
class
InstanceHandle
:
NonNullHandle
{
PlayingStatus
,
PauseStatus
,
ForwardStatus
,
BackwardStatus
,
InitStatus
,
EndStatus
,
UndefinedStatus
,
};
enum
PositionOrigin
private
InstanceHandle
()
{
AbsolutePosition
,
RelativePosition
,
ModuloPosition
,
};
}
enum
PositionKey
{
ByteCount
,
SampleCount
,
MediaTime
,
};
[
DllImport
(
"libvlc-control.dll"
,
EntryPoint
=
"libvlc_new"
)]
public
static
extern
InstanceHandle
Create
(
int
argc
,
U8String
[]
argv
,
NativeException
ex
);
MediaControlHandle
self
;
[
DllImport
(
"libvlc-control.dll"
,
EntryPoint
=
"libvlc_destroy"
)]
static
extern
void
Destroy
(
InstanceHandle
ptr
,
NativeException
ex
);
pr
ivate
void
CheckDisposed
()
pr
otected
override
bool
ReleaseHandle
()
{
if
(
self
.
IsInvalid
)
throw
new
ObjectDisposedException
(
"Media controlled disposed"
)
;
Destroy
(
this
,
null
);
return
true
;
}
};
/**
* Creates a MediaControl with a new LibVLC instance
*/
public
MediaControl
(
string
[]
args
)
public
class
VLCInstance
:
IDisposable
{
NativeException
e
=
NativeException
.
Prepare
();
NativeException
ex
;
InstanceHandle
self
;
public
VLCInstance
(
string
[]
args
)
{
U8String
[]
argv
=
new
U8String
[
args
.
Length
];
for
(
int
i
=
0
;
i
<
args
.
Length
;
i
++)
argv
[
i
]
=
new
U8String
(
args
[
i
]);
self
=
MediaControlAPI
.
New
(
argv
.
Length
,
argv
,
ref
e
);
e
.
Consume
();
ex
=
new
NativeException
();
self
=
InstanceHandle
.
Create
(
argv
.
Length
,
argv
,
ex
);
ex
.
Raise
();
}
/**
* Creates a MediaControl from an existing LibVLC instance
*/
/*public MediaControl (MediaControl instance)
{
NativeException e = NativeException.Prepare ();
IntPtr libvlc = mediacontrol_get_libvlc_instance (instance.self);
self = mediacontrol_new_from_instance (libvlc, ref e);
e.Consume ();
}*/
/*public void Play (from)
{
CheckDisposed ();
throw new NotImplementedException ();
}*/
public
void
Resume
()
{
CheckDisposed
();
NativeException
e
=
NativeException
.
Prepare
();
MediaControlAPI
.
Resume
(
self
,
IntPtr
.
Zero
,
ref
e
);
e
.
Consume
();
}
public
void
Pause
()
{
CheckDisposed
();
NativeException
e
=
NativeException
.
Prepare
();
MediaControlAPI
.
Pause
(
self
,
IntPtr
.
Zero
,
ref
e
);
e
.
Consume
();
}
public
void
Stop
()
{
CheckDisposed
();
NativeException
e
=
NativeException
.
Prepare
();
MediaControlAPI
.
Stop
(
self
,
IntPtr
.
Zero
,
ref
e
);
e
.
Consume
();
}
public
void
AddItem
(
string
mrl
)
{
CheckDisposed
();
U8String
nmrl
=
new
U8String
(
mrl
);
NativeException
e
=
NativeException
.
Prepare
();
MediaControlAPI
.
PlaylistAddItem
(
self
,
nmrl
,
ref
e
);
e
.
Consume
();
}
public
void
Clear
()
{
CheckDisposed
();
NativeException
e
=
NativeException
.
Prepare
();
MediaControlAPI
.
PlaylistClear
(
self
,
ref
e
);
e
.
Consume
();
}
public
string
[]
Playlist
{
get
public
void
Dispose
()
{
CheckDisposed
();
throw
new
NotImplementedException
();
}
ex
.
Dispose
();
self
.
Close
();
}
/**
* Switches to the next playlist item
*/
public
void
NextItem
()
public
MediaDescriptor
CreateDescriptor
(
string
mrl
)
{
CheckDisposed
();
U8String
umrl
=
new
U8String
(
mrl
);
DescriptorHandle
dh
=
DescriptorHandle
.
Create
(
self
,
umrl
,
ex
);
ex
.
Raise
();
NativeException
e
=
NativeException
.
Prepare
();
MediaControlAPI
.
PlaylistNextItem
(
self
,
ref
e
);
e
.
Consume
();
return
new
MediaDescriptor
(
dh
);
}
};
/**
* Normalized audio output volume in percent (must be [0..100]).
*/
public
short
SoundVolume
/** Safe handle for unmanaged LibVLC media descriptor */
internal
sealed
class
DescriptorHandle
:
NonNullHandle
{
get
private
DescriptorHandle
()
{
CheckDisposed
();
NativeException
e
=
NativeException
.
Prepare
();
short
vol
=
MediaControlAPI
.
SoundGetVolume
(
self
,
ref
e
);
e
.
Consume
();
return
vol
;
}
set
{
CheckDisposed
();
if
((
value
<
0
)
||
(
value
>
100
))
throw
new
ArgumentOutOfRangeException
(
"Volume not within [0..100]"
);
NativeException
e
=
NativeException
.
Prepare
();
MediaControlAPI
.
SoundSetVolume
(
self
,
value
,
ref
e
);
e
.
Consume
();
}
}
[
DllImport
(
"libvlc-control.dll"
,
EntryPoint
=
"libvlc_media_descriptor_new"
)]
public
static
extern
DescriptorHandle
Create
(
InstanceHandle
inst
,
U8String
mrl
,
NativeException
ex
);
/**
* Performance speed rate in percent.
*/
public
int
Rate
{
get
{
CheckDisposed
();
[
DllImport
(
"libvlc-control.dll"
,
EntryPoint
=
"libvlc_media_descriptor_release"
)]
public
static
extern
void
Release
(
DescriptorHandle
ptr
);
NativeException
e
=
NativeException
.
Prepare
();
int
rate
=
MediaControlAPI
.
GetRate
(
self
,
ref
e
);
e
.
Consume
();
return
rate
;
}
set
protected
override
bool
ReleaseHandle
()
{
CheckDisposed
();
NativeException
e
=
NativeException
.
Prepare
();
MediaControlAPI
.
SetRate
(
self
,
value
,
ref
e
);
e
.
Consume
();
}
Release
(
this
);
return
true
;
}
};
/**
* Fullscreen flag.
*/
public
bool
Fullscreen
{
get
{
CheckDisposed
();
NativeException
e
=
NativeException
.
Prepare
();
int
ret
=
MediaControlAPI
.
GetFullscreen
(
self
,
ref
e
);
e
.
Consume
();
return
ret
!=
0
;
}
set
public
class
MediaDescriptor
{
CheckDisposed
();
NativeException
ex
;
DescriptorHandle
self
;
NativeException
e
=
NativeException
.
Prepare
();
MediaControlAPI
.
SetFullscreen
(
self
,
value
?
1
:
0
,
ref
e
);
e
.
Consume
();
}
}
public
void
Dispose
()
internal
MediaDescriptor
(
DescriptorHandle
self
)
{
self
.
Dispose
();
this
.
self
=
self
;
ex
=
new
NativeException
();
}
};
};
bindings/cil/marshal.cs
View file @
77aa5b9e
...
...
@@ -24,49 +24,8 @@
using
System
;
using
System.Runtime.InteropServices
;
namespace
VideoLAN.VLC
namespace
VideoLAN.
Lib
VLC
{
internal
class
MediaControlAPI
{
[
DllImport
(
"libvlc-control.dll"
,
EntryPoint
=
"mediacontrol_new"
)]
public
static
extern
MediaControlHandle
New
(
int
argc
,
U8String
[]
argv
,
ref
NativeException
e
);
[
DllImport
(
"libvlc-control.dll"
,
EntryPoint
=
"mediacontrol_exit"
)]
public
static
extern
void
Exit
(
IntPtr
self
);
[
DllImport
(
"libvlc-control.dll"
,
EntryPoint
=
"mediacontrol_start"
)]
public
static
extern
void
Start
(
MediaControlHandle
self
,
IntPtr
pos
,
ref
NativeException
e
);
[
DllImport
(
"libvlc-control.dll"
,
EntryPoint
=
"mediacontrol_pause"
)]
public
static
extern
void
Pause
(
MediaControlHandle
self
,
IntPtr
dummy
,
ref
NativeException
e
);
[
DllImport
(
"libvlc-control.dll"
,
EntryPoint
=
"mediacontrol_resume"
)]
public
static
extern
void
Resume
(
MediaControlHandle
self
,
IntPtr
dummy
,
ref
NativeException
e
);
[
DllImport
(
"libvlc-control.dll"
,
EntryPoint
=
"mediacontrol_stop"
)]
public
static
extern
void
Stop
(
MediaControlHandle
self
,
IntPtr
dummy
,
ref
NativeException
e
);
[
DllImport
(
"libvlc-control.dll"
,
EntryPoint
=
"mediacontrol_playlist_add_item"
)]
public
static
extern
void
PlaylistAddItem
(
MediaControlHandle
self
,
U8String
mrl
,
ref
NativeException
e
);
[
DllImport
(
"libvlc-control.dll"
,
EntryPoint
=
"mediacontrol_playlist_clear"
)]
public
static
extern
void
PlaylistClear
(
MediaControlHandle
self
,
ref
NativeException
e
);
[
DllImport
(
"libvlc-control.dll"
,
EntryPoint
=
"mediacontrol_playlist_get_list"
)]
public
static
extern
IntPtr
PlaylistGetList
(
MediaControlHandle
self
,
ref
NativeException
e
);
[
DllImport
(
"libvlc-control.dll"
,
EntryPoint
=
"mediacontrol_playlist_next_item"
)]
public
static
extern
void
PlaylistNextItem
(
MediaControlHandle
self
,
ref
NativeException
e
);
[
DllImport
(
"libvlc-control.dll"
,
EntryPoint
=
"mediacontrol_sound_get_volume"
)]
public
static
extern
short
SoundGetVolume
(
MediaControlHandle
self
,
ref
NativeException
e
);
[
DllImport
(
"libvlc-control.dll"
,
EntryPoint
=
"mediacontrol_sound_set_volume"
)]
public
static
extern
void
SoundSetVolume
(
MediaControlHandle
self
,
short
volume
,
ref
NativeException
e
);
/* SetVisual */
[
DllImport
(
"libvlc-control.dll"
,
EntryPoint
=
"mediacontrol_get_rate"
)]
public
static
extern
short
GetRate
(
MediaControlHandle
self
,
ref
NativeException
e
);
[
DllImport
(
"libvlc-control.dll"
,
EntryPoint
=
"mediacontrol_set_rate"
)]
public
static
extern
void
SetRate
(
MediaControlHandle
self
,
int
rate
,
ref
NativeException
e
);
[
DllImport
(
"libvlc-control.dll"
,
EntryPoint
=
"mediacontrol_get_fullscreen"
)]
public
static
extern
int
GetFullscreen
(
MediaControlHandle
self
,
ref
NativeException
e
);
[
DllImport
(
"libvlc-control.dll"
,
EntryPoint
=
"mediacontrol_set_fullscreen"
)]
public
static
extern
void
SetFullscreen
(
MediaControlHandle
self
,
int
full
,
ref
NativeException
e
);
};
/**
* Abstract safe handle class for non-NULL pointers
* (Microsoft.* namespace has a similar class, but lets stick to System.*)
...
...
@@ -82,133 +41,7 @@ namespace VideoLAN.VLC
{
get
{
return
IsClosed
||
(
handle
==
IntPtr
.
Zero
);
}
}
};
internal
sealed
class
MediaControlHandle
:
NonNullHandle
{
private
MediaControlHandle
()
{
}
protected
override
bool
ReleaseHandle
()
{
MediaControlAPI
.
Exit
(
handle
);
return
true
;
}
};
/**
* Wrapper around native UTF-8 nul-terminated character arrays
*/
[
StructLayout
(
LayoutKind
.
Sequential
)]
internal
sealed
struct
U8String
{
byte
[]
mb_str
;
public
U8String
(
string
value
)
{
byte
[]
bytes
=
System
.
Text
.
Encoding
.
UTF8
.
GetBytes
(
value
);
mb_str
=
new
byte
[
bytes
.
Length
+
1
];
Array
.
Copy
(
bytes
,
mb_str
,
bytes
.
Length
);
mb_str
[
bytes
.
Length
]
=
0
;
}
public
U8String
(
IntPtr
ptr
)
{
if
(
ptr
==
IntPtr
.
Zero
)
return
;
int
i
=
0
;
while
(
Marshal
.
ReadByte
(
ptr
,
i
)
!=
0
)
i
++;
i
++;
mb_str
=
new
byte
[
i
];
Marshal
.
Copy
(
ptr
,
mb_str
,
0
,
i
);
}
public
override
string
ToString
()
{
if
(
mb_str
==
null
)
return
null
;
byte
[]
bytes
=
new
byte
[
mb_str
.
Length
-
1
];
Array
.
Copy
(
mb_str
,
bytes
,
bytes
.
Length
);
return
System
.
Text
.
Encoding
.
UTF8
.
GetString
(
bytes
);
}
};
/**
* LibVLC native exception structure
*/
[
StructLayout
(
LayoutKind
.
Sequential
)]
internal
sealed
struct
NativeException
{
public
int
code
;
public
IntPtr
message
;
public
string
Message
{
get
{
return
new
U8String
(
message
).
ToString
();
}
}
[
DllImport
(
"libvlc-control.dll"
)]
static
extern
void
mediacontrol_exception_init
(
ref
NativeException
e
);
[
DllImport
(
"libvlc-control.dll"
)]
static
extern
void
mediacontrol_exception_cleanup
(
ref
NativeException
e
);
public
static
NativeException
Prepare
()
{
NativeException
e
=
new
NativeException
();
mediacontrol_exception_init
(
ref
e
);
return
e
;
}
public
void
Consume
()
{
try
{
Exception
e
;
string
m
=
Message
;
switch
(
this
.
code
)
{
case
0
:
e
=
null
;
break
;
case
1
:
e
=
new
PositionKeyNotSupportedException
(
m
);
break
;
case
2
:
e
=
new
PositionOriginNotSupportedException
(
m
);
break
;
case
3
:
e
=
new
InvalidPositionException
(
m
);
break
;
case
4
:
e
=
new
PlaylistException
(
m
);
break
;
case
5
:
e
=
new
InternalException
(
m
);
break
;
default
:
e
=
new
MediaException
(
m
);
break
;
}
if
(
e
!=
null
)
throw
e
;
}
finally
{
mediacontrol_exception_cleanup
(
ref
this
);
return
handle
==
IntPtr
.
Zero
;
}
}
};
...
...
bindings/cil/testvlc.cs
View file @
77aa5b9e
...
...
@@ -22,6 +22,7 @@
**********************************************************************/
using
System
;
using
VideoLAN.LibVLC
;
namespace
VideoLAN.VLC
{
...
...
@@ -29,25 +30,7 @@ namespace VideoLAN.VLC
{
public
static
int
Main
(
string
[]
args
)
{
MediaControl
mc
=
new
MediaControl
(
args
);
foreach
(
string
s
in
args
)
mc
.
AddItem
(
s
);
Console
.
WriteLine
(
"Volume : {0}%"
,
mc
.
SoundVolume
);
Console
.
WriteLine
(
"Rate : {0}%"
,
mc
.
Rate
);
Console
.
WriteLine
(
"Fullscreen: {0}"
,
mc
.
Fullscreen
);
mc
.
Fullscreen
=
false
;
/*mc.Play ();*/
Console
.
ReadLine
();
mc
.
Stop
();
mc
.
Clear
();
mc
.
SoundVolume
=
100
;
mc
.
Rate
=
100
;
mc
.
Dispose
();
VLCInstance
vlc
=
new
VLCInstance
(
args
);
return
0
;
}
};
...
...
bindings/cil/ustring.cs
0 → 100644
View file @
77aa5b9e
/*
* ustring.cs - Managed LibVLC string
*
* $Id$
*/
/**********************************************************************
* Copyright (C) 2007 Rémi Denis-Courmont. *
* This program is free software; you can redistribute and/or modify *
* it under the terms of the GNU General Public License as published *
* by the Free Software Foundation; version 2 of the license, or (at *
* your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, you can get it from: *
* http://www.gnu.org/copyleft/gpl.html *
**********************************************************************/
using
System
;
using
System.Runtime.InteropServices
;
namespace
VideoLAN.LibVLC
{
/**
* Managed class for UTF-8 nul-terminated character arrays
*/
[
StructLayout
(
LayoutKind
.
Sequential
)]
public
sealed
struct
U8String
{
public
byte
[]
mb_str
;
public
U8String
(
string
value
)
{
byte
[]
bytes
=
System
.
Text
.
Encoding
.
UTF8
.
GetBytes
(
value
);
mb_str
=
new
byte
[
bytes
.
Length
+
1
];
Array
.
Copy
(
bytes
,
mb_str
,
bytes
.
Length
);
mb_str
[
bytes
.
Length
]
=
0
;
}
public
U8String
(
IntPtr
ptr
)
{
if
(
ptr
==
IntPtr
.
Zero
)
return
;
int
i
=
0
;
while
(
Marshal
.
ReadByte
(
ptr
,
i
)
!=
0
)
i
++;
i
++;
mb_str
=
new
byte
[
i
];
Marshal
.
Copy
(
ptr
,
mb_str
,
0
,
i
);
}
public
override
string
ToString
()
{
if
(
mb_str
==
null
)
return
null
;
byte
[]
bytes
=
new
byte
[
mb_str
.
Length
-
1
];
Array
.
Copy
(
mb_str
,
bytes
,
bytes
.
Length
);
return
System
.
Text
.
Encoding
.
UTF8
.
GetString
(
bytes
);
}
public
static
string
FromNative
(
IntPtr
ptr
)
{
return
new
U8String
(
ptr
).
ToString
();
}
};
};
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment