1

I am recently working with one type library requirement. I have created a c# class that will be exposed to COM component. However, when I set a value to an array property I get a compiler error. All the code are placed here.

Looking forward to your expert comments!

(VBA) Compile error:
Function or interface marked as restricted, or the function uses an Automation type not supported in Visual Basic

C# Com Class

[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(_LeafletTestClass))]
[ProgId("Leaflet.WebService.Toolkit.LeafletWS.LeafletTestClass")]
[Guid("364C5E66-4412-48E3-8BD8-7B2BF09E8922")]
public class LeafletTestClass : _LeafletTestClass
{
    [ComVisible(true)]
    public string[] TestArrayString
    {
        [return: MarshalAs(UnmanagedType.SafeArray)]
        get;
        [param: MarshalAs(UnmanagedType.SafeArray)]
        set;
    }

}

[ComVisible(true)]
[Guid("8C034F6A-1D3F-4DB8-BC99-B73873D8C297")]
public interface _LeafletTestClass
{
    [ComVisible(true)]
    string[] TestArrayString
    {
        get;
        set;
    }
}

VBA Create Object

Sub test()

Dim testClass As LeafletTestClass
Set testClass = New LeafletTestClass
Dim arr(0 To 1) As String
arr(0) = "Test value"
testClass.TestArrayString = arr

End Sub
11
  • I am getting a compiler error. Commented Aug 10, 2018 at 19:50
  • Sorry I completely missed it in your post, it looked like a code block Commented Aug 10, 2018 at 20:03
  • Why are you using ClassInterfaceType.None? Any particular reason? Commented Aug 10, 2018 at 20:08
  • 2
    Reg free COM or not, it's still good principle to ensure that you are not generating junk metadata. Yes, it's nice that COM interop helps you out, but it can only help naively; taking control ensures that it won't suddenly behave in a weird way when your implementation changes and thus trip up the assumptions the COM interop makes about your COM interfaces. Commented Aug 10, 2018 at 20:18
  • 1
    stackoverflow.com/questions/13185159/… Commented Aug 10, 2018 at 22:20

1 Answer 1

3

I would recommend that you avoid using arrays. While you can use Marshal and possibly marshal it across it is fraught with issues due to difference in how empty arrays and nulls are handled, etc. etc.

To avoid runtime errors, you are better off writing a collection class and marshaling that across so that VBA can then simply enumerate. For an example of this, see here

At minimum your collection interface need to look like this:

[
    ComVisible(true),
    Guid(<some guid>),
    InterfaceType(ComInterfaceType.InterfaceIsDual)
]
public interface IDeclarations : IEnumerable
{
    [DispId(0)]
    Declaration Item(int Index);

    [DispId(1)]
    int Count { get; }

    [DispId(-4)]
    IEnumerator _GetEnumerator();
 }
Sign up to request clarification or add additional context in comments.

2 Comments

I am still not getting how to replace this with Array.
Can you elaborate more -- what have you tried and what isn't working?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.