7

If I define a class in a C#/.NET class library, then by making it COM visible I can instantiate the class and call its methods from VBA using COM.

Is there any way to call the static methods of such a class from VBA?

Gary McGill
  • 26,400
  • 25
  • 118
  • 202
  • 2
    http://msdn.microsoft.com/en-us/library/ms182198.aspx is it your question? – Jack Malkovich Jun 12 '14 at 20:15
  • 1
    You would need to make an instance method that wraps the static method for COM. – vcsjones Jun 12 '14 at 20:17
  • @JackMalkovich: The link says "COM does not support static methods", so yes, that does answer my question ("no"). Feel free to put that as an answer. – Gary McGill Jun 12 '14 at 20:34
  • @vcsjones: Yes, I could, but that's what I was trying to avoid. I have a class for which a default constructor is not desirable, and I was planning to have a static Create() method to allow COM callers to create them. Looks like the Create method will have to be an instance member of another class. What a PITA. – Gary McGill Jun 12 '14 at 20:35
  • 1
    You can do `Dim ClassObject: Set ClassObject = GetObject("clsid:CLSID")` (where `CLSID` is the string formatter class ID without *{* and *}*) to fetch a class object. I never tried with a C#/.NET class, but if classes support IDispatch, you can use it to do `Dim Object: Set Object = ClassObject.Create()`, instead of the more common `Dim Object: Set Object = CreateObject("Prog.Id")` which will call the class's `IClassFactory::CreateInstance`. Nonetheless, I highly recommend you to create a proper factory. – acelent Jun 12 '14 at 20:42
  • So, I tried it, and it seems that .NET class factories (I'm not sure if all go through a common entry point, mscoree.dll's `DllGetClassObject`) only implement `IUnknown` and `IClassFactory`. For COM-style static classes/methods/properties, only with a COM server, where you'd `CoRegisterClassObject` an instance of a class that actually implements `IClassFactory` in managed code. Meaning, since this is not a usual thing to do in COM anyway, don't do it or rely on it. – acelent Jun 13 '14 at 15:50
  • Possible duplicate of [How can I invoke a static method on a .NET object over COM interop?](https://stackoverflow.com/questions/1395897/how-can-i-invoke-a-static-method-on-a-net-object-over-com-interop) – StayOnTarget May 04 '18 at 15:21

2 Answers2

12

COM does not support static methods, and instances of COM objects do not invoke static methods. Instead, set ComVisible(false) on your static method, then make an instance method to wrap it:

[ComVisible(true)]
public class Foo
{
    [ComVisible(false)]
    public static void Bar() {}

    public void BarInst()
    {
        Bar();
    }
}

Or just make the method instance instead of static and forget static all together.

You don't have to mark the static method as not visible to COM, however it satisfies some code analysis tools that would warn you about static methods on COM visible types, and makes it clear that the static method is not intended to be visible to COM.

vcsjones
  • 138,677
  • 31
  • 291
  • 286
2

COM does not support static methods.

http://msdn.microsoft.com/en-us/library/ms182198.aspx

Jack Malkovich
  • 786
  • 13
  • 33