4

For example, the DOM specification has various IDL definitions, one of which is the Interface Node. How would you go about translating this—even a portion of this—into actual C#? I mean, where would you even start? As far as I understand, C#'s interfaces behave much differently than what IDL is calling an interface here. Am I wrong?

interface Node {

  // NodeType
  const unsigned short      ELEMENT_NODE                   = 1;
  const unsigned short      ATTRIBUTE_NODE                 = 2;
  const unsigned short      TEXT_NODE                      = 3;
  const unsigned short      CDATA_SECTION_NODE             = 4;
  const unsigned short      ENTITY_REFERENCE_NODE          = 5;
  const unsigned short      ENTITY_NODE                    = 6;
  const unsigned short      PROCESSING_INSTRUCTION_NODE    = 7;
  const unsigned short      COMMENT_NODE                   = 8;
  const unsigned short      DOCUMENT_NODE                  = 9;
  const unsigned short      DOCUMENT_TYPE_NODE             = 10;
  const unsigned short      DOCUMENT_FRAGMENT_NODE         = 11;
  const unsigned short      NOTATION_NODE                  = 12;

  readonly attribute DOMString       nodeName;
           attribute DOMString       nodeValue;
                                        // raises(DOMException) on setting
                                        // raises(DOMException) on retrieval

  readonly attribute unsigned short  nodeType;
  readonly attribute Node            parentNode;
  readonly attribute NodeList        childNodes;
  readonly attribute Node            firstChild;
  readonly attribute Node            lastChild;
  readonly attribute Node            previousSibling;
  readonly attribute Node            nextSibling;
  readonly attribute NamedNodeMap    attributes;
  // Modified in DOM Level 2:
  readonly attribute Document        ownerDocument;
  // Modified in DOM Level 3:
  Node               insertBefore(in Node newChild, 
                                  in Node refChild)
                                        raises(DOMException);
  // Modified in DOM Level 3:
  Node               replaceChild(in Node newChild, 
                                  in Node oldChild)
                                        raises(DOMException);
  // Modified in DOM Level 3:
  Node               removeChild(in Node oldChild)
                                        raises(DOMException);
  // Modified in DOM Level 3:
  Node               appendChild(in Node newChild)
                                        raises(DOMException);
  boolean            hasChildNodes();
  Node               cloneNode(in boolean deep);
  // Modified in DOM Level 3:
  void               normalize();
  // Introduced in DOM Level 2:
  boolean            isSupported(in DOMString feature, 
                                 in DOMString version);
  // Introduced in DOM Level 2:
  readonly attribute DOMString       namespaceURI;
  // Introduced in DOM Level 2:
           attribute DOMString       prefix;
                                        // raises(DOMException) on setting

  // Introduced in DOM Level 2:
  readonly attribute DOMString       localName;
  // Introduced in DOM Level 2:
  boolean            hasAttributes();
  // Introduced in DOM Level 3:
  readonly attribute DOMString       baseURI;

  // DocumentPosition
  const unsigned short      DOCUMENT_POSITION_DISCONNECTED = 0x01;
  const unsigned short      DOCUMENT_POSITION_PRECEDING    = 0x02;
  const unsigned short      DOCUMENT_POSITION_FOLLOWING    = 0x04;
  const unsigned short      DOCUMENT_POSITION_CONTAINS     = 0x08;
  const unsigned short      DOCUMENT_POSITION_CONTAINED_BY = 0x10;
  const unsigned short      DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20;

  // Introduced in DOM Level 3:
  unsigned short     compareDocumentPosition(in Node other)
                                        raises(DOMException);
  // Introduced in DOM Level 3:
           attribute DOMString       textContent;
                                        // raises(DOMException) on setting
                                        // raises(DOMException) on retrieval

  // Introduced in DOM Level 3:
  boolean            isSameNode(in Node other);
  // Introduced in DOM Level 3:
  DOMString          lookupPrefix(in DOMString namespaceURI);
  // Introduced in DOM Level 3:
  boolean            isDefaultNamespace(in DOMString namespaceURI);
  // Introduced in DOM Level 3:
  DOMString          lookupNamespaceURI(in DOMString prefix);
  // Introduced in DOM Level 3:
  boolean            isEqualNode(in Node arg);
  // Introduced in DOM Level 3:
  DOMObject          getFeature(in DOMString feature, 
                                in DOMString version);
  // Introduced in DOM Level 3:
  DOMUserData        setUserData(in DOMString key, 
                                 in DOMUserData data, 
                                 in UserDataHandler handler);
  // Introduced in DOM Level 3:
  DOMUserData        getUserData(in DOMString key);
};
jedmao
  • 10,224
  • 11
  • 59
  • 65
  • 1
    Kind-of-duplicate-but-not-quite ;) http://stackoverflow.com/questions/1307675/convert-interface-idl-file-to-c – viraptor Jul 24 '10 at 13:48
  • That's very interesting, but I'd still like to see someone answer the question by actually translating this—or even a portion of this—into C#. My guess would be that it wouldn't be an interface at all, but a class. – jedmao Jul 24 '10 at 18:26

1 Answers1

7

Background

In C#, an interface is by definition empty and has many possible implementations. In COM, in general, an interface will have one implementation and defines a calling contract, not an implementation contract (like with web services or CORBA). In C#, the implementation of an interface is .NET specific. In COM, the implementation of an interface is a language-neutral, but a binary implementation (as opposed to SOAP messages, which is textual/XML). This binary definition has always been food for criticasters of COM and the slow (if at all) adoption of COM on non-Windows systems (again, as opposed to web services).

For practically all IDL commands, there's an equivalent possibility in C#, albeit not always within just in interface. The base interface of COM is always IUknown, which is used for object reference counting, which must be included by all COM objects.

In speech, when talking about a COM interface, you usually talk about an implementation. In c#, you usually talk about the empty contracts that callers and implementers understand.

Translate IDL

The IDL above is for DOM, as you mention. The DOM is implemented in C# and is much more powerful than its COM cousins (and many versions). If you really want to create a C# class wrapper that can call the COM DOM interfaces:

  • use MIDL (comes with Visual Studio) to create a TLB,
  • then run tlbimp.exe (comes with .NET) to create a .NET COM wrapper, which you can include in your project.

You can also run tlbimp.exe directly on the COM dlls (in process) or executables (out of process) to create a .NET COM Wrapper.

More information

A basic, yet extremely brilliant and thorough introduction to COM is Don Box's famous book Essential COM, about IDL I suggest Essential IDL by Gudgin.

Absolutely everything there is to know about COM and .NET is written down in the comprehensive, yet slightly bloated, .NET and .COM The Complete Interoperability Guide by Nathan. Not a book you will read from cover to cover, but it makes excellent reference material.

Abel
  • 56,041
  • 24
  • 146
  • 247
  • I just don't like the way that the DOM is implemented into C#. That is, if you are referring to the `System.Web.UI` and `System.Web.UI.HtmlControls` namespaces. What I'm looking for is more like something that forces me to write HTML to W3C specification and won't even compile if I somehow screw it up. For example, if I try to add a certain type of attribute or content to an inappropriate element. Maybe I'll post a separate question for this one. Do you know of anything like this? – jedmao Jul 24 '10 at 14:14
  • 1
    @sfjedi: the `System.Web` namespace is not what you want to refer to when using XML DOM. It has a different purpose: HTML, which is much more than just XML (and much less in other respects). What you should look for is the `System.Xml` namespaces with `XmlDocument` and, if you like LINQ (through `System.Linq.Xml`), the `XDocument`. Both are fully compatible with XML and DOM and are much further evoluted than MS's COM interfaces ever got. – Abel Jul 24 '10 at 14:17
  • Yes and I'm very familiar with `System.Linq.Xml` and `XDocument` and although they are quite impressive and useful, they still don't come anywhere close to what I'm trying to do, which is prevent the developer from compiling code that isn't to specification. – jedmao Jul 24 '10 at 14:43