Skip to content

Commit ba2eec0

Browse files
author
dahall
committed
Fixed bug in generated TypeDef IConvertible.ToType method
1 parent 94c008f commit ba2eec0

3 files changed

Lines changed: 52 additions & 4 deletions

File tree

CodeGen/Generator/TypeDefTemplate.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ public readonly bool TryFormat(Span<char> destination, out int charsWritten, Rea
313313
readonly float IConvertible.ToSingle(IFormatProvider? provider) => ((IConvertible)Value).ToSingle(provider);
314314

315315
/// <inheritdoc/>
316-
readonly object IConvertible.ToType(Type conversionType, IFormatProvider? provider) => ((IConvertible)Value).ToType(conversionType, provider);
316+
readonly object IConvertible.ToType(Type conversionType, IFormatProvider? provider) => conversionType == typeof(__TYPENAME__) ? this : ((IConvertible)Value).ToType(conversionType, provider);
317317

318318
/// <inheritdoc/>
319319
readonly ushort IConvertible.ToUInt16(IFormatProvider? provider) => ((IConvertible)Value).ToUInt16(provider);

Core/ForwardDeclarations/WinDef/BOOL.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
using Vanara.Marshaler;
2-
using Vanara.PInvoke;
1+
using Vanara.PInvoke;
32

43
namespace Vanara;
54

65
/// <summary>Managed instance of the four-byte BOOL type.</summary>
7-
[TypeDef(typeof(uint), ConvertTo = typeof(bool), Excludes = ExcludeOptions.Numerics)]
6+
[TypeDef(typeof(uint), ConvertTo = typeof(bool), Excludes = ExcludeOptions.Numerics, GetConvValue = "value != 0", SetConvValue = "value ? True : False")]
87
public partial struct BOOL
98
{
109
internal const uint True = 1U;

UnitTests/Core/WinDef/BOOLTest.cs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,41 @@
11
using NUnit.Framework;
2+
using System.Collections.Concurrent;
3+
using System.Linq;
4+
using System.Reflection;
25

36
namespace Vanara.PInvoke.Tests;
47

58
[TestFixture]
69
public class BOOLTests
710
{
11+
private static readonly ConcurrentDictionary<Type, bool> cachedTypes = [];
12+
private static bool IsUnmanagedType(Type t)
13+
{
14+
var result = false;
15+
if (cachedTypes.TryGetValue(t, out bool value))
16+
return value;
17+
else if (t.IsPrimitive || t.IsPointer || t.IsEnum)
18+
result = true;
19+
else if (t.IsGenericType || !t.IsValueType)
20+
result = false;
21+
else
22+
result = t.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).All(x => IsUnmanagedType(x.FieldType));
23+
cachedTypes[t] = result;
24+
return result;
25+
}
26+
27+
[Test]
28+
public void IsUnmanagedTypeTest()
29+
{
30+
byte[] buffer = new byte[4];
31+
Assert.That(IsUnmanagedType(typeof(BOOL)));
32+
Assert.That(() => Marshal.StructureToPtr((object)new BOOL(true), Marshal.UnsafeAddrOfPinnedArrayElement(buffer, 0), false), Throws.Nothing);
33+
Assert.That(buffer[0], Is.EqualTo(1));
34+
35+
Assert.That(IsUnmanagedType(typeof(BOOLEAN)));
36+
Assert.That(IsUnmanagedType(typeof(VARIANT_BOOL)));
37+
}
38+
839
[Test]
940
public void BOOLTest()
1041
{
@@ -74,6 +105,24 @@ public void BOOLIConvertibleTest()
74105
Assert.That(Convert.ChangeType(b, typeof(bool)), Is.EqualTo(true));
75106
}
76107

108+
[Test]
109+
public void BOOLMemTest()
110+
{
111+
using SafeCoTaskMemStruct<BOOL> mem = (BOOL)true;
112+
}
113+
114+
[Test]
115+
public void BOOLEANMemTest()
116+
{
117+
using SafeCoTaskMemStruct<BOOLEAN> mem = (BOOLEAN)true;
118+
}
119+
120+
[Test]
121+
public void VARIANT_BOOLMemTest()
122+
{
123+
using SafeCoTaskMemStruct<VARIANT_BOOL> mem = (VARIANT_BOOL)true;
124+
}
125+
77126
[Test]
78127
public void BOOLEANTest()
79128
{

0 commit comments

Comments
 (0)