Skip to content

Commit

Permalink
fix: Ignore properties/methods with ComVisible=false
Browse files Browse the repository at this point in the history
  • Loading branch information
marklechtermann committed Nov 20, 2023
1 parent 12df665 commit 4c240b9
Showing 1 changed file with 36 additions and 24 deletions.
60 changes: 36 additions & 24 deletions src/dscom/writer/InterfaceWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
// limitations under the License.

using System.Globalization;
using System.Reflection;
using System.Runtime.InteropServices;

namespace dSPACE.Runtime.InteropServices.Writer;
Expand All @@ -34,7 +35,7 @@ public InterfaceWriter(Type sourceType, LibraryWriter libraryWriter, WriterConte

public abstract Guid BaseInterfaceGuid { get; }

protected List<MethodWriter> MethodWriter { get; } = new();
protected List<MethodWriter?> MethodWriters { get; } = new();

private ITypeInfo? BaseTypeInfo { get; set; }

Expand Down Expand Up @@ -72,7 +73,7 @@ public override void Create()
DispatchIdCreator.NormalizeIds();

// Create all writer.
MethodWriter.ForEach(writer => writer.Create());
MethodWriters.ForEach(writer => writer?.Create());

TypeInfo.LayOut().ThrowIfFailed($"Failed to layout type {SourceType}.");
}
Expand All @@ -84,43 +85,54 @@ private void CreateMethodWriters()

foreach (var method in methods)
{
var numIdenticalNames = MethodWriter.Count(z => z.IsVisibleMethod && (z.MemberInfo.Name == method.Name || z.MethodName.StartsWith(method.Name + "_", StringComparison.Ordinal)));
var numIdenticalNames = MethodWriters.Count(z => z is not null && z.IsVisibleMethod && (z.MemberInfo.Name == method.Name || z.MethodName.StartsWith(method.Name + "_", StringComparison.Ordinal)));

numIdenticalNames += GetMethodNamesOfBaseTypeInfo(BaseTypeInfo).Count(z => z == method.Name || z.StartsWith(method.Name + "_", StringComparison.Ordinal));

var alternateName = numIdenticalNames == 0 ? method.Name : method.Name + "_" + (numIdenticalNames + 1).ToString(CultureInfo.InvariantCulture);
MethodWriter? methodWriter = null;
if ((method.Name.StartsWith("get_", StringComparison.Ordinal) || method.Name.StartsWith("set_", StringComparison.Ordinal)) && method.IsSpecialName)
{
alternateName = alternateName.Substring(4);
if (method.Name.StartsWith("get_", StringComparison.Ordinal))
{
methodWriter = new PropertyGetMethodWriter(this, method, Context, alternateName);
}
else
if (method.Name.StartsWith("set_", StringComparison.Ordinal))
var propertyInfo = method.DeclaringType!.GetProperties().First(p => p.GetGetMethod() == method || p.GetSetMethod() == method);
var comVisibleAttribute = propertyInfo.GetCustomAttribute<ComVisibleAttribute>();

if (comVisibleAttribute is null || comVisibleAttribute.Value)
{
methodWriter = new PropertySetMethodWriter(this, method, Context, alternateName);
alternateName = alternateName.Substring(4);
if (method.Name.StartsWith("get_", StringComparison.Ordinal))
{
methodWriter = new PropertyGetMethodWriter(this, method, Context, alternateName);
}
else
if (method.Name.StartsWith("set_", StringComparison.Ordinal))
{
methodWriter = new PropertySetMethodWriter(this, method, Context, alternateName);
}
}
}
else
{
methodWriter = new(this, method, Context, alternateName);
}
if (methodWriter != null)
{
MethodWriter.Add(methodWriter);
var comVisibleAttribute = method.GetCustomAttribute<ComVisibleAttribute>();
if (comVisibleAttribute is null || comVisibleAttribute.Value)
{
methodWriter = new(this, method, Context, alternateName);
}
}

MethodWriters.Add(methodWriter);
}

var index = 0;
var functionIndex = 0;
foreach (var methodWriter in MethodWriter)
foreach (var methodWriter in MethodWriters)
{
methodWriter.FunctionIndex = functionIndex;
methodWriter.VTableOffset = VTableOffsetUserMethodStart + (index * IntPtr.Size);
DispatchIdCreator!.RegisterMember(methodWriter);
functionIndex += methodWriter.IsValid ? 1 : 0;
if (methodWriter is not null)
{
methodWriter.FunctionIndex = functionIndex;
methodWriter.VTableOffset = VTableOffsetUserMethodStart + (index * IntPtr.Size);
DispatchIdCreator!.RegisterMember(methodWriter);
functionIndex += methodWriter.IsValid ? 1 : 0;
}
index++;
}
}
Expand Down Expand Up @@ -163,10 +175,10 @@ private static IEnumerable<string> GetMethodNamesOfBaseTypeInfo(ITypeInfo? typeI

protected override void Dispose(bool disposing)
{
if (MethodWriter != null)
if (MethodWriters != null)
{
MethodWriter.ForEach(t => t.Dispose());
MethodWriter.Clear();
MethodWriters.ForEach(t => t?.Dispose());
MethodWriters.Clear();
}

base.Dispose(disposing);
Expand Down

0 comments on commit 4c240b9

Please sign in to comment.