[ObjCRuntime/bgen] Add support for (s)byte, (u)short and nuint fields. (#21141)
This commit is contained in:
Родитель
bd35d0d2e5
Коммит
56de4fa92e
|
@ -203,6 +203,114 @@ namespace ObjCRuntime {
|
|||
return Runtime.GetNSObject<NSNumber> (actual);
|
||||
}
|
||||
|
||||
/// <summary>Gets the signed byte value exposed with the given symbol from the dynamic library.</summary>
|
||||
/// <param name="handle">Handle to the dynamic library previously opened with <see cref="dlopen(System.String,System.Int32)" /> or <see cref="dlopen(System.String,Mode)" />.</param>
|
||||
/// <param name="symbol">Name of the public symbol in the dynamic library to look up.</param>
|
||||
/// <returns>The value from the library, or zero on failure.</returns>
|
||||
/// <remarks>If this routine fails, it will return zero.</remarks>
|
||||
public static sbyte GetSByte (IntPtr handle, string symbol)
|
||||
{
|
||||
var indirect = dlsym (handle, symbol);
|
||||
if (indirect == IntPtr.Zero)
|
||||
return 0;
|
||||
unchecked {
|
||||
return (sbyte) Marshal.ReadByte (indirect);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Sets the specified symbol in the library handle to the specified signed byte value.</summary>
|
||||
/// <param name="handle">Handle to the dynamic library previously opened with <see cref="dlopen(System.String,System.Int32)" /> or <see cref="dlopen(System.String,Mode)" />.</param>
|
||||
/// <param name="symbol">Name of the public symbol in the dynamic library to look up.</param>
|
||||
/// <param name="value">The value to set.</param>
|
||||
public static void SetSByte (IntPtr handle, string symbol, sbyte value)
|
||||
{
|
||||
var indirect = dlsym (handle, symbol);
|
||||
if (indirect == IntPtr.Zero)
|
||||
return;
|
||||
unsafe {
|
||||
Marshal.WriteByte (indirect, (byte) value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Gets the byte value exposed with the given symbol from the dynamic library.</summary>
|
||||
/// <param name="handle">Handle to the dynamic library previously opened with <see cref="dlopen(System.String,System.Int32)" /> or <see cref="dlopen(System.String,Mode)" />.</param>
|
||||
/// <param name="symbol">Name of the public symbol in the dynamic library to look up.</param>
|
||||
/// <returns>The value from the library, or zero on failure.</returns>
|
||||
/// <remarks>If this routine fails, it will return zero.</remarks>
|
||||
public static byte GetByte (IntPtr handle, string symbol)
|
||||
{
|
||||
var indirect = dlsym (handle, symbol);
|
||||
if (indirect == IntPtr.Zero)
|
||||
return 0;
|
||||
return Marshal.ReadByte (indirect);
|
||||
}
|
||||
|
||||
/// <summary>Sets the specified symbol in the library handle to the specified byte value.</summary>
|
||||
/// <param name="handle">Handle to the dynamic library previously opened with <see cref="dlopen(System.String,System.Int32)" /> or <see cref="dlopen(System.String,Mode)" />.</param>
|
||||
/// <param name="symbol">Name of the public symbol in the dynamic library to look up.</param>
|
||||
/// <param name="value">The value to set.</param>
|
||||
public static void SetByte (IntPtr handle, string symbol, byte value)
|
||||
{
|
||||
var indirect = dlsym (handle, symbol);
|
||||
if (indirect == IntPtr.Zero)
|
||||
return;
|
||||
Marshal.WriteByte (indirect, value);
|
||||
}
|
||||
|
||||
/// <summary>Gets the short value exposed with the given symbol from the dynamic library.</summary>
|
||||
/// <param name="handle">Handle to the dynamic library previously opened with <see cref="dlopen(System.String,System.Int32)" /> or <see cref="dlopen(System.String,Mode)" />.</param>
|
||||
/// <param name="symbol">Name of the public symbol in the dynamic library to look up.</param>
|
||||
/// <returns>The value from the library, or zero on failure.</returns>
|
||||
/// <remarks>If this routine fails, it will return zero.</remarks>
|
||||
public static short GetInt16 (IntPtr handle, string symbol)
|
||||
{
|
||||
var indirect = dlsym (handle, symbol);
|
||||
if (indirect == IntPtr.Zero)
|
||||
return 0;
|
||||
return Marshal.ReadInt16 (indirect);
|
||||
}
|
||||
|
||||
/// <summary>Sets the specified symbol in the library handle to the specified short value.</summary>
|
||||
/// <param name="handle">Handle to the dynamic library previously opened with <see cref="dlopen(System.String,System.Int32)" /> or <see cref="dlopen(System.String,Mode)" />.</param>
|
||||
/// <param name="symbol">Name of the public symbol in the dynamic library to look up.</param>
|
||||
/// <param name="value">The value to set.</param>
|
||||
public static void SetInt16 (IntPtr handle, string symbol, short value)
|
||||
{
|
||||
var indirect = dlsym (handle, symbol);
|
||||
if (indirect == IntPtr.Zero)
|
||||
return;
|
||||
Marshal.WriteInt16 (indirect, value);
|
||||
}
|
||||
|
||||
/// <summary>Gets the ushort value exposed with the given symbol from the dynamic library.</summary>
|
||||
/// <param name="handle">Handle to the dynamic library previously opened with <see cref="dlopen(System.String,System.Int32)" /> or <see cref="dlopen(System.String,Mode)" />.</param>
|
||||
/// <param name="symbol">Name of the public symbol in the dynamic library to look up.</param>
|
||||
/// <returns>The value from the library, or zero on failure.</returns>
|
||||
/// <remarks>If this routine fails, it will return zero.</remarks>
|
||||
public static ushort GetUInt16 (IntPtr handle, string symbol)
|
||||
{
|
||||
var indirect = dlsym (handle, symbol);
|
||||
if (indirect == IntPtr.Zero)
|
||||
return 0;
|
||||
unchecked {
|
||||
return (ushort) Marshal.ReadInt16 (indirect);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Sets the specified symbol in the library handle to the specified ushort value.</summary>
|
||||
/// <param name="handle">Handle to the dynamic library previously opened with <see cref="dlopen(System.String,System.Int32)" /> or <see cref="dlopen(System.String,Mode)" />.</param>
|
||||
/// <param name="symbol">Name of the public symbol in the dynamic library to look up.</param>
|
||||
/// <param name="value">The value to set.</param>
|
||||
public static void SetUInt16 (IntPtr handle, string symbol, ushort value)
|
||||
{
|
||||
var indirect = dlsym (handle, symbol);
|
||||
if (indirect == IntPtr.Zero)
|
||||
return;
|
||||
unchecked {
|
||||
Marshal.WriteInt16 (indirect, (short) value);
|
||||
}
|
||||
}
|
||||
|
||||
public static int GetInt32 (IntPtr handle, string symbol)
|
||||
{
|
||||
var indirect = dlsym (handle, symbol);
|
||||
|
|
|
@ -6339,6 +6339,14 @@ public partial class Generator : IMemberGatherer {
|
|||
print ("_{0} = Runtime.GetNSObject<UTType> (Dlfcn.GetIntPtr (Libraries.{2}.Handle, \"{1}\"))!;", field_pi.Name, fieldAttr.SymbolName, library_name);
|
||||
indent--;
|
||||
print ("return _{0};", field_pi.Name);
|
||||
} else if (field_pi.PropertyType == TypeCache.System_Byte) {
|
||||
print ("return Dlfcn.GetByte (Libraries.{2}.Handle, \"{1}\");", field_pi.Name, fieldAttr.SymbolName, library_name);
|
||||
} else if (field_pi.PropertyType == TypeCache.System_SByte) {
|
||||
print ("return Dlfcn.GetSByte (Libraries.{2}.Handle, \"{1}\");", field_pi.Name, fieldAttr.SymbolName, library_name);
|
||||
} else if (field_pi.PropertyType == TypeCache.System_Int16) {
|
||||
print ("return Dlfcn.GetInt16 (Libraries.{2}.Handle, \"{1}\");", field_pi.Name, fieldAttr.SymbolName, library_name);
|
||||
} else if (field_pi.PropertyType == TypeCache.System_UInt16) {
|
||||
print ("return Dlfcn.GetUInt16 (Libraries.{2}.Handle, \"{1}\");", field_pi.Name, fieldAttr.SymbolName, library_name);
|
||||
} else if (field_pi.PropertyType == TypeCache.System_Int32) {
|
||||
print ("return Dlfcn.GetInt32 (Libraries.{2}.Handle, \"{1}\");", field_pi.Name, fieldAttr.SymbolName, library_name);
|
||||
} else if (field_pi.PropertyType == TypeCache.System_UInt32) {
|
||||
|
@ -6349,6 +6357,8 @@ public partial class Generator : IMemberGatherer {
|
|||
print ("return Dlfcn.GetFloat (Libraries.{2}.Handle, \"{1}\");", field_pi.Name, fieldAttr.SymbolName, library_name);
|
||||
} else if (field_pi.PropertyType == TypeCache.System_IntPtr) {
|
||||
print ("return Dlfcn.GetIntPtr (Libraries.{2}.Handle, \"{1}\");", field_pi.Name, fieldAttr.SymbolName, library_name);
|
||||
} else if (field_pi.PropertyType == TypeCache.System_UIntPtr) {
|
||||
print ("return Dlfcn.GetUIntPtr (Libraries.{2}.Handle, \"{1}\");", field_pi.Name, fieldAttr.SymbolName, library_name);
|
||||
} else if (field_pi.PropertyType.FullName == "System.Drawing.SizeF") {
|
||||
print ("return Dlfcn.GetSizeF (Libraries.{2}.Handle, \"{1}\");", field_pi.Name, fieldAttr.SymbolName, library_name);
|
||||
} else if (field_pi.PropertyType == TypeCache.System_Int64) {
|
||||
|
@ -6419,10 +6429,20 @@ public partial class Generator : IMemberGatherer {
|
|||
print ("Dlfcn.SetUInt32 (Libraries.{2}.Handle, \"{1}\", value);", field_pi.Name, fieldAttr.SymbolName, library_name);
|
||||
} else if (field_pi.PropertyType == TypeCache.System_Double) {
|
||||
print ("Dlfcn.SetDouble (Libraries.{2}.Handle, \"{1}\", value);", field_pi.Name, fieldAttr.SymbolName, library_name);
|
||||
} else if (field_pi.PropertyType == TypeCache.System_Byte) {
|
||||
print ("Dlfcn.SetByte (Libraries.{2}.Handle, \"{1}\", value);", field_pi.Name, fieldAttr.SymbolName, library_name);
|
||||
} else if (field_pi.PropertyType == TypeCache.System_SByte) {
|
||||
print ("Dlfcn.SetSByte (Libraries.{2}.Handle, \"{1}\", value);", field_pi.Name, fieldAttr.SymbolName, library_name);
|
||||
} else if (field_pi.PropertyType == TypeCache.System_Int16) {
|
||||
print ("Dlfcn.SetInt16 (Libraries.{2}.Handle, \"{1}\", value);", field_pi.Name, fieldAttr.SymbolName, library_name);
|
||||
} else if (field_pi.PropertyType == TypeCache.System_UInt16) {
|
||||
print ("Dlfcn.SetUInt16 (Libraries.{2}.Handle, \"{1}\", value);", field_pi.Name, fieldAttr.SymbolName, library_name);
|
||||
} else if (field_pi.PropertyType == TypeCache.System_Float) {
|
||||
print ("Dlfcn.SetFloat (Libraries.{2}.Handle, \"{1}\", value);", field_pi.Name, fieldAttr.SymbolName, library_name);
|
||||
} else if (field_pi.PropertyType == TypeCache.System_IntPtr) {
|
||||
print ("Dlfcn.SetIntPtr (Libraries.{2}.Handle, \"{1}\", value);", field_pi.Name, fieldAttr.SymbolName, library_name);
|
||||
} else if (field_pi.PropertyType == TypeCache.System_UIntPtr) {
|
||||
print ("Dlfcn.SetUIntPtr (Libraries.{2}.Handle, \"{1}\", value);", field_pi.Name, fieldAttr.SymbolName, library_name);
|
||||
} else if (field_pi.PropertyType.FullName == "System.Drawing.SizeF") {
|
||||
print ("Dlfcn.SetSizeF (Libraries.{2}.Handle, \"{1}\", value);", field_pi.Name, fieldAttr.SymbolName, library_name);
|
||||
} else if (field_pi.PropertyType == TypeCache.System_Int64) {
|
||||
|
|
|
@ -1675,6 +1675,22 @@ namespace GeneratorTests {
|
|||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase (Profile.iOS)]
|
||||
public void UnderlyingFieldType (Profile profile)
|
||||
{
|
||||
Configuration.IgnoreIfIgnoredPlatform (profile.AsPlatform ());
|
||||
var bgen = BuildFile (profile, true, true, "tests/underlyingfieldtype.cs");
|
||||
|
||||
#if NET
|
||||
const string nintName = "System.IntPtr";
|
||||
const string nuintName = "System.UIntPtr";
|
||||
#else
|
||||
const string nintName = "System.nint";
|
||||
const string nuintName = "System.nuint";
|
||||
#endif
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase (Profile.iOS)]
|
||||
public void DelegatesWithNullableReturnType (Profile profile)
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
using System;
|
||||
using Foundation;
|
||||
|
||||
namespace UnderlyingFieldType {
|
||||
[BaseType (typeof (NSObject))]
|
||||
interface FieldClass {
|
||||
[Field ("SByteField", "__Internal")]
|
||||
sbyte SByteField { get; set; }
|
||||
|
||||
[Field ("ByteField", "__Internal")]
|
||||
byte ByteField { get; set; }
|
||||
|
||||
[Field ("ShortField", "__Internal")]
|
||||
short ShortField { get; set; }
|
||||
|
||||
[Field ("UShortField", "__Internal")]
|
||||
ushort UShortField { get; set; }
|
||||
|
||||
[Field ("IntField", "__Internal")]
|
||||
int IntField { get; set; }
|
||||
|
||||
[Field ("UIntField", "__Internal")]
|
||||
uint UIntField { get; set; }
|
||||
|
||||
[Field ("LongField", "__Internal")]
|
||||
long LongField { get; set; }
|
||||
|
||||
[Field ("ULongField", "__Internal")]
|
||||
ulong ULongField { get; set; }
|
||||
|
||||
[Field ("DoubleField", "__Internal")]
|
||||
double DoubleField { get; set; }
|
||||
|
||||
[Field ("UIntPtrField", "__Internal")]
|
||||
UIntPtr UIntPtrField { get; set; }
|
||||
|
||||
[Field ("IntPtrield", "__Internal")]
|
||||
IntPtr IntPtrField { get; set; }
|
||||
}
|
||||
}
|
|
@ -33,5 +33,83 @@ namespace MonoTouchFixtures.ObjCRuntime {
|
|||
#endif
|
||||
Assert.That (err, Is.EqualTo (expected), "dlclose");
|
||||
}
|
||||
|
||||
#if NET
|
||||
[Test]
|
||||
public void GetVariables ()
|
||||
{
|
||||
var symbol = "x_native_field";
|
||||
var handle = (IntPtr) Dlfcn.RTLD.Default;
|
||||
|
||||
Assert.AreNotEqual (IntPtr.Zero, Dlfcn.dlsym (handle, symbol), "Symbol");
|
||||
|
||||
var originalValue = Dlfcn.GetUInt64 (handle, symbol);
|
||||
Assert.Multiple (() => {
|
||||
unchecked {
|
||||
// the n(uint) and (U)IntPtr asserts only work in 64-bit, which is fine because we only care about 64-bit right now.
|
||||
Assert.AreEqual ((ushort) 0x8899, (ushort) Dlfcn.GetInt16 (handle, symbol), "GetInt16");
|
||||
Assert.AreEqual ((uint) 0xeeff8899, (uint) Dlfcn.GetInt32 (handle, symbol), "GetInt32");
|
||||
Assert.AreEqual ((ulong) 0xaabbccddeeff8899, (ulong) Dlfcn.GetInt64 (handle, symbol), "GetInt64");
|
||||
Assert.AreEqual ((nuint) 0xaabbccddeeff8899, (nuint) Dlfcn.GetNInt (handle, symbol), "GetNInt");
|
||||
Assert.AreEqual ((ushort) 0x8899, Dlfcn.GetUInt16 (handle, symbol), "GetUInt16");
|
||||
Assert.AreEqual ((uint) 0xeeff8899, Dlfcn.GetUInt32 (handle, symbol), "GetUInt32");
|
||||
Assert.AreEqual ((ulong) 0xaabbccddeeff8899, Dlfcn.GetUInt64 (handle, symbol), "GetUInt64");
|
||||
Assert.AreEqual ((nuint) 0xaabbccddeeff8899, Dlfcn.GetNUInt (handle, symbol), "GetNUInt");
|
||||
Assert.AreEqual ((nfloat) (-7.757653393002521E-103), Dlfcn.GetNFloat (handle, symbol), "GetNFloat");
|
||||
Assert.AreEqual (-7.7576533930025207E-103d, Dlfcn.GetDouble (handle, symbol), "GetDouble");
|
||||
Assert.AreEqual ((nuint) 0xaabbccddeeff8899, (nuint) Dlfcn.GetIntPtr (handle, symbol), "GetIntPtr"); // won't work in 32-bit, but we don't care about that anymore
|
||||
Assert.AreEqual ((nuint) 0xaabbccddeeff8899, Dlfcn.GetUIntPtr (handle, symbol), "GetUIntPtr");
|
||||
|
||||
Dlfcn.SetInt16 (handle, symbol, 0x77);
|
||||
Assert.AreEqual ((short) 0x77, Dlfcn.GetInt16 (handle, symbol), "SetInt16");
|
||||
Dlfcn.SetUInt64 (handle, symbol, originalValue);
|
||||
|
||||
Dlfcn.SetInt32 (handle, symbol, 0x77);
|
||||
Assert.AreEqual ((int) 0x77, Dlfcn.GetInt32 (handle, symbol), "SetInt32");
|
||||
Dlfcn.SetUInt64 (handle, symbol, originalValue);
|
||||
|
||||
Dlfcn.SetInt64 (handle, symbol, 0x77);
|
||||
Assert.AreEqual ((long) 0x77, Dlfcn.GetInt64 (handle, symbol), "SetInt64");
|
||||
Dlfcn.SetUInt64 (handle, symbol, originalValue);
|
||||
|
||||
Dlfcn.SetNInt (handle, symbol, 0x77);
|
||||
Assert.AreEqual ((nint) 0x77, Dlfcn.GetNInt (handle, symbol), "SetNInt");
|
||||
Dlfcn.SetUInt64 (handle, symbol, originalValue);
|
||||
|
||||
Dlfcn.SetUInt16 (handle, symbol, 0x77);
|
||||
Assert.AreEqual ((ushort) 0x77, Dlfcn.GetUInt16 (handle, symbol), "SetUInt16");
|
||||
Dlfcn.SetUInt64 (handle, symbol, originalValue);
|
||||
|
||||
Dlfcn.SetUInt32 (handle, symbol, 0x77);
|
||||
Assert.AreEqual ((uint) 0x77, Dlfcn.GetUInt32 (handle, symbol), "SetUInt32");
|
||||
Dlfcn.SetUInt64 (handle, symbol, originalValue);
|
||||
|
||||
Dlfcn.SetUInt64 (handle, symbol, 0x77);
|
||||
Assert.AreEqual ((ulong) 0x77, Dlfcn.GetUInt64 (handle, symbol), "SetUInt64");
|
||||
Dlfcn.SetUInt64 (handle, symbol, originalValue);
|
||||
|
||||
Dlfcn.SetNUInt (handle, symbol, 0x77);
|
||||
Assert.AreEqual ((nuint) 0x77, Dlfcn.GetNUInt (handle, symbol), "SetNUInt");
|
||||
Dlfcn.SetUInt64 (handle, symbol, originalValue);
|
||||
|
||||
Dlfcn.SetNFloat (handle, symbol, 0x77);
|
||||
Assert.AreEqual ((nfloat) 0x77, Dlfcn.GetNFloat (handle, symbol), "SetNFloat");
|
||||
Dlfcn.SetUInt64 (handle, symbol, originalValue);
|
||||
|
||||
Dlfcn.SetDouble (handle, symbol, 0x77);
|
||||
Assert.AreEqual (0x77, Dlfcn.GetDouble (handle, symbol), "SetDouble");
|
||||
Dlfcn.SetUInt64 (handle, symbol, originalValue);
|
||||
|
||||
Dlfcn.SetIntPtr (handle, symbol, 0x77);
|
||||
Assert.AreEqual ((nint) 0x77, Dlfcn.GetIntPtr (handle, symbol), "SetIntPtr");
|
||||
Dlfcn.SetUInt64 (handle, symbol, originalValue);
|
||||
|
||||
Dlfcn.SetUIntPtr (handle, symbol, 0x77);
|
||||
Assert.AreEqual ((nuint) 0x77, Dlfcn.GetUIntPtr (handle, symbol), "SetUIntPtr");
|
||||
Dlfcn.SetUInt64 (handle, symbol, originalValue);
|
||||
}
|
||||
});
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<ReferenceNativeSymbol Include="Inexistent" SymbolType="ObjectiveCClass" SymbolMode="Ignore" />
|
||||
<ReferenceNativeSymbol Include="x_native_field" SymbolType="Field" />
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="$(RootTestsDirectory)/common/shared-dotnet.csproj" />
|
||||
|
|
|
@ -17,6 +17,8 @@ extern "C" {
|
|||
int theUltimateAnswer ();
|
||||
void useZLib ();
|
||||
|
||||
__attribute__ ((used)) unsigned long long x_native_field = 0xAABBCCDDEEFF8899;
|
||||
|
||||
// NS_ASSUME_NONNULL_BEGIN doesn't work
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wnullability-completeness"
|
||||
|
|
|
@ -74,6 +74,7 @@
|
|||
#define x_SCNMatrix4MakeScale object_x_SCNMatrix4MakeScale
|
||||
#define x_SCNMatrix4Translate object_x_SCNMatrix4Translate
|
||||
#define x_GlobalString object_x_GlobalString
|
||||
#define x_native_field object_x_native_field
|
||||
#elif PREFIX == 2
|
||||
#define theUltimateAnswer ar_theUltimateAnswer
|
||||
#define useZLib ar_useZLib
|
||||
|
@ -149,6 +150,7 @@
|
|||
#define x_SCNMatrix4MakeScale ar_x_SCNMatrix4MakeScale
|
||||
#define x_SCNMatrix4Translate ar_x_SCNMatrix4Translate
|
||||
#define x_GlobalString ar_x_GlobalString
|
||||
#define x_native_field ar_x_native_field
|
||||
#else
|
||||
// keep original names
|
||||
#endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче