Essential COM

Don Box

Mentioned 22

Shows developers how COM operates and how to use it to create efficient and stable programs consistent with the COM philosophy, allowing disparate applications and components to work together across a variety of languages, platforms, and host machines. Original. (Advanced).

More on

Mentioned in questions and answers.

I am curious about COM+, DCOM. I know that MSFT does not encourage you to use this tools natively (meaning with C/C++, in fact there is not a lot of documentation available) but I want to learn to use these technologies, like embedding Internet Explorer into a C program.

I thought that maybe I could find people that worked with this or that knows about this technology.

Where to start? Any ideas? Any example (like Hello World DCOM)?

COM, COM+ and DCOM are three completely different things. At this point, there is very little reason to learn COM and almost no reason to learn DCOM. The only reason I can think of is if you have to maintain or integrate legacy components. COM+ is still used because it allows for out of process hosting of components and nice things like distributed transaction management.

The best way to start writing up some COM is using ATL. In .NET COM+ is called Enterprise Services.

The best book I know on COM is Don Box's Essential COM and Tim Ewald's COM+ book is excellent too.

Actually, if you want to learn more about COM, Microsoft publishes a book about COM and how it works...

If I have a struct in c++, is there no way to safely read/write it to a file that is cross-platform/compiler compatible? Because if I understand correctly, every compiler 'pads' differently based on the target platform.

No. That is not possible. It's because of lack of standardization of C++ at the binary level.

Don Box writes (quoting from his book Essential COM, chapter COM As A Better C++)

C++ and Portability

Once the decision is made to distribute a C++ class as a DLL, one is faced with one of the fundamental weaknesses of C++, that is, lack of standardization at the binary level. Although the ISO/ANSI C++ Draft Working Paper attempts to codify which programs will compile and what the semantic effects of running them will be, it makes no attempt to standardize the binary runtime model of C++. The first time this problem will become evident is when a client tries to link against the FastString DLL's import library from a C++ developement environment other than the one used to build the FastString DLL.

struct-padding is done differently by different compilers. Even if you use the same compiler, the packing alignment for structs can be different based on what pragma pack you're using.

Not only that if you write two structs whose members are exactly same, the only difference is that the order in which they're declared is different, then size of each struct can be (and often is) different.

For example, see this,

struct A
   char c;
   char d;
   int i;
struct B
   char c;
   int i;
   char d;
int main() {
        cout << sizeof(A) << endl;
        cout << sizeof(B) << endl;

Compile it with gcc-4.3.4, and you get this output:


That is, sizes are different even though both structs has same members!

Code at Ideone :

The bottomline is that the Standard doesn't talk about how padding should be done, and so the compilers are free to make any decision and you cannot assume all compilers make the same decision.

I searched hard, but was unable to grasp the whole idea. Can anyone tell me:

  • What COM actually is?
  • How do GUIDs work, and how are they used by COM?
  • How does COM resolve the issues of different DLL versions.

Or at least, point me to a good article somewhere that explains these concepts? Thanks!

COM is Microsoft's Component Object Model, a binary-compatible interface for programs written in various languages to interoperate with each other. It is the "evolutionary step" between the OLE and .NET technologies.

If you want to learn about COM from the C++ perspective, take a look at Don Box's Essential COM, or ATL Internals by Rector and Sells.

The group is probably the best place to ask questions you can't get answers for here. It's primarily an ATL newsgroup, but it seems to be the newsgroup with the most traffic for general COM questions as well. (just be prepared for the usual newsgroup curtness & impatience)

Your question is a little large for a full explanation here. A quick high-level introduction to COM can be found in the book Understanding ActiveX and OLE. A more detailed but still introductory introduction is Inside COM. The best book on the subject is Don Box's Essential COM.

A couple of quick answers:

  • COM is a binary interface standard for objects. It allows various programs to write to interfaces without all having to have been written in the same langauge with the same compiler. There are also related services available.
  • GUIDs are globally unique numbers that COM uses to identify interfaces.
  • COM doesn't resolve different DLL version problems. It only allows a single DLL to be registered for each GUID.

Sometimes I see the term "free-threaded" to describe a class or a method. It seems to have a similar or identical meaning to "thread-safe".

Is there a difference between the two terms?

I've just done some research on what "free-threaded" might mean, and I also ended up with COM. Let me first cite two passages from the 1998 edition of Don Box' book Essential COM. (The book actually contains more sections about the free-threaded model, but I'll leave it at that for now.)

A thread executes in exactly one apartment at a time. Before a thread can use COM, it must first enter an apartment. […] COM defines two types of apartments: multithreaded apartments (MTAs) and singlethreaded apartments (STAs). Each process has at most one MTA; however, a process can contain multiple STAs. As their names imply, multiple threads can execute in an MTA concurrently, whereas only one thread can execute in an STA. […]

— from pages 200-201. (Emphasis added by me.)

Each CLSID in a DLL can have its own distinct ThreadingModel. […]

  • ThreadingModel="Both" indicates that the class can execute in either an MTA or an STA.
  • ThreadingModel="Free" indicates that the class can execute only in an MTA.
  • ThreadingModel="Apartment" indicates that the class can execute only in an STA.
  • The absence of a ThreadingModel value implies that the class can run only on the main STA. The main STA is defined as the first STA to be initialized in the process.

— from page 204. (Formatting and emphasis added by me.)

I take this to mean that a component (class) who is declared as free-threaded runs in an MTA, where concurrency of several threads is possible and calls to the component from different threads is explicitly allowed; ie. a free-threaded component supports a multithreaded environment. It would obviously have to be thread-safe in order to achieve this.

The opposite would be a component that is designed for an STA, ie. only allows calls from one particular thread. Such a class would not have to be thread-safe (because COM will take care that no other thread than the one who "entered" / set up the STA can use the component in the first place, that is, COM protects the component from concurrent access).

Conclusion: COM's term "free-threaded" essentially seems to have the same implications as the more general term "thread-safe".

P.S.: This answer assumes that "thread-safe" basically means something like, "can deal with concurrent accesses (possibly by different threads)."

P.P.S.: I do wonder whether "free-threaded" is the opposite of "having thread affinity".

Does CoCreateInstance automatically calls AddRef on the interface I'm creating or should I call it manually afterwards?

The contract with COM is anytime you are handed an object from a function like this, such as CoCreateInstance(), QueryInterface() (which is what CoCreateInstance() ultimately calls), etc, the callee always calls AddRef() before returning, and the caller (you) always Release() when you are done.

You can use CComPtr<> to make this simpler, and it just does the right thing.

Now if you need to hand this pointer out to another object that expects it to be usable beyond the lifetime of your object, then you need to call AddRef() before giving it out.

I recommend Essential COM by Don Box for further reading on this topic.

I'd like to learn programming with windows libraries. Could You recommend me some technical books / tutorials. I'm not looking for a book for beginers, lets asume that the reader knows C++/OOP/STDLIB/STL.

Topics I need to be covered are ~ WinAPI (Base/Advanced Services), MFC, COM, ATL and possibly WTL if it makes sense. I'm not trying to learn .NET,C# and so on.

Thanks for help.

For Win32 nothing beats Programming Windows by Petzold and Windows via C/C++ by Ricther for COM, certainly Essential COM by Don Box and there is even a new edition of ATL Internals. Once you know the Win32 API the MFC layer on top of that is mostly learnable via MSDN, so I don't have a good recommendation there.

The topics you are interested in are generally too broad to be covered in depth by a single book. Having said that, you can check this one: - it covers most of the topics you are interested in, even if it is a bit outdated.

I am a fresh graduate with a bachelor in Computer Science. As most school today, they are no longer teaching students C or advance C++ (only an Introductory course in C++... With lessons up to Pointers). The standard programming language prescribed in the curriculum is C# (.NET stack).

Just recently, I got hired as a junior software developer. 95% of our codebase is in C++ and our products are using COM/DCOM. The other 5% is in .NET. My current responsibility is to maintain a project written in .NET (ASP.NET) and I am not required to study C++ and other technology YET. But I want to learn COM as soon as possible so I can help out on other projects.

So I am seeking the advice of this community on how I can go about learning COM. My current questions are the following:

  1. Any required reading? (Pre-requisite topics)
  2. A Good Site in Learning the basics of COM?
  3. A type of Simple Program to really appreciate the "purpose" of COM (A chat program perhaps?)

Thanks! :)

PS: Should I mark this as a community wiki?

The book of Don Box about COM is the definitive reference. Amazon link.

Beware is a tough read, but it covers everything in deep. And remember, as Don said... COM IS LOVE.

I do not believe you can find a lot of web site, COM was a up to date technology a lot of time ago, but if you can forgot about it trust me... it's better!

I would recommend the book ATL Internals, it may be getting a bit old but it will teach you the basic fundamentals of COM. As the tho poster commented, the Don Box is good as well.

To learn the very basic ideas behind COM, I've never come across anything better than Inside COM by Dale Rogerson. This is an old book, but it explains very clearly why COM is needed and how it is implemented, and you can pick up a second hand copy on Amazon.

As for the Don Box books, I've read all of them and I think they are pretty damn poor. Box neverr explains the motivation for the code he descrribes and uses deeply unrealistic examples. But I realise this is a minority opinion.

I'm looking at getting into ActiveX development and hopefully make a couple browser plug-ins by the end of things. I'm a seasoned WinAPI developer who has stayed away from such wrappers as MFC and ATL in the past, so I have virtually no experience in either area. However, in searching for tutorials on creating ActiveX controls in C++, they almost invariably involve either one of those two standards, which wouldn't work for me. My question is, is it possible to create an ActiveX control (suitable for embedding in IE) without touching MFC or ATL? If so, does anyone have any good references or tutorials I could read on the subject? If not, what do you guys recommend as my best path forward? How hard would it be for me to pick up VB and do things that way?

Thanks in advance

Yes, it's definitely possible but not for the faint of heart. I would recommend books by Don Box (Essential COM) to learn about the fundamentals of COM.

MFC and ATL and other framework have a lot of plumbing already in place that you're free to replicate yourself if you like.

folks can you provide me the tutorial link or .pdf for learning basic COM?. i do google it.. still i recommend answers of stackoverflow so please pass me..


Though you have asked for links, I would recommend you the book: Inside COM by Dale Rogerson.

I would recommend Essential COM by Don Box. He explains things from the bottom up, and gives you the Why as well as the How

I am trying to build an app that uses a COM component in VisualStudio ยด05 in native C++. The mix of native and managed desciptions of things in the MSDN totally wrecked my brain. (I think the MSDN is a total mess in that respect) I need a short and simple native C++ sample of code to load my Component and make it usable. I am ok with the compiler creating wrappers and the like.

Please don't advise me to use the dialog based MFC example, because it does not work with this component and is in itself a huge pile of c... code.

Can this be an issue native com vs managed com?

I am totally lost, please give me some bearings...

EDIT: Thanks for all the help. My problem is that all I have is a registered dll (actually the OCX, see below) . I (personally) know what the Interface should look like, but how do I tell my program? There are no headers that define IDs for Interfaces that I could use. But I read that the c++ compiler can extract and wrap it up for me. Anyone know how this is done?

CLARIFICATION: I have only the OCX and a clue from the documentation of the component, what methods it should expose.

I applaud your efforts to go with native C++ to deal with COM - you need to go through the pain to truly appreciate today's luxurious (managed) development environment :)

Back when the world (and I) were younger, Kraig Brockshmidt's book "Inside OLE" was the tome for making sense of COM (before COM even was COM). This book predates managed code, so no chance of managed confusion here. There's a second edition, too.

Don Box's books "Essential COM" and "Effective COM" were later, but welcome additions to the store of (unmanaged) COM knowledge.

However, if your wallet doesn't extend to acquiring these dusty old books, the Microsoft COM tutorial material here could help set you on the right track.

Happy hacking.

Why does IClassFactory::LockServer exist when it seems to me that IClassFactory::AddRef / IClassFactory::Release can accomplish the same goal?

This is explained in detail in Don Box's book Essential COM.

AddRef/Release on IClassFactory interfaces of class objects are often empty methods in out-of-process COM servers. This is because an internal reference to the class object is maintained by the server when it calls CoRegisterClassObject, and thus the "normal" in-process server implementation of AddRef/Release would result in the reference count on the class object always exceeding one, and the server would not know when to call CoRevokeClassObject.

The COM runtime calls IClassFactory::LockServer when it marshals an external reference to a class object following a call to CoGetClassObject. In this way the server process lifetime can be properly controlled based on the existence or otherwise of external references.

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)
  // Modified in DOM Level 3:
  Node               replaceChild(in Node newChild, 
                                  in Node oldChild)
  // Modified in DOM Level 3:
  Node               removeChild(in Node oldChild)
  // Modified in DOM Level 3:
  Node               appendChild(in Node newChild)
  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)
  // 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);


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.

I'm currently reading this text on COM:

I'm up to the bit about COM Classes, also know as "CoClasses." I totally get what they are, what they do, and how they relate to interfaces.

But here's my question: what exactly does the "Co" in "CoClass" mean? Is it "Co" as in "cooperate," or "co" as in "concrete," or "co" as in "COM," or "co" as in something else entirely?

CO is for "Component Object". Check the official documentation for IDL here: coclass attribute

The coclass statement provides a listing of the supported interfaces for a component object.

And an old article about COM here: Understanding Interface Definition Language: A Developer's Survival Guide

"The coclass statement is used to define a component object and the interfaces that it supports"

To better myself I am attempting to make my dll's COM compliant, I thought I'd just need to extend/implement a few interfaces and job done but now I am at a cross roads,

1) Should I learn MIDL?

2) Should I install the ATL (I am running VC++Express)?

3) Carry on reading the C++ tutorials ( and hope my Express edition is too limited?

1) Yes. If you are going to define new interfaces, you pretty much have to. It's not impossible to do without MIDL, but it's way harder than to learn basic MIDL.

2) Yes, please do. It'll hide much of the boiler plate code (which is tedious to write, and error prone).

3) I would recommend the book Essential COM by Don Box. It's awesome. Also, a great companion to that book is Essential IDL by Martin Gudgin.

As for VC++ Express - I have never used them. I guess it's possible to do COM with it, but with limited tool/library support.

I am studying COM. I think the best way to get a thorough understanding of COM is write one without any COM framework such as ATL. I have written a COM server in raw C++, and now I want to write one in plain raw C. How could I do this? Is there any tutorial?

Many thanks.

Don Box's book Essential COM is one of the best that explains everything about COM from the ground up. Recommended.

COM, however, is decade old technology that's a heck of a lot of work to do in C, and Don Box (previously considered one of the experts) doesn't even touch it anymore. Take what you will from that.

I've always used the following rule for signatures of functions that return ref-counted objects based on whether they do an AddRef or not, but want to explain it to my colleagues too... So my question is, is the rule described below a widely followed rule? I'm looking for pointers to (for example) coding rules that advocate this style.

If the function does not add a reference to the object, it should be returned as the return value of the function:

class MyClass
    IUnknown *getObj() { return m_obj; }
    IUnknown *m_obj;

However, if the function adds a reference to the object, then a pointer-to-pointer of the object is passed as a parameter to the function:

class MyClass
    void getObj(IUnknown **outObj) { *outObj = m_obj; (*outObj)->AddRef(); }
    IUnknown *m_obj;

I've used this same style on projects with a lot of COM. It was taught to me by a couple of people that learned it when they worked at NuMega on a little thing called SoftICE. I think this is also the style taught in the book "Essential COM", by Don Box (here it is at Amazon). At one point in time this book was considered the Bible for COM. I think the only reason this isn't still the case is that COM has become so much more than just COM.

All that said, I prefer CComPtr and other smart pointers.

I have a class which inherits from IDirectInputA interface.


so, when i try to create object of this, application crashes (calls CorExitProcess from somewhere). What i did wrong?

p.s. Direct input v. 7


this code creates object. I deleted some code from it, except the main part

IDirectInputA** ppDI;
HRESULT hr = _DirectInputCreateA(hinst, dwVersion, ppDI, punkOuter);
xDirectInputA xDI = new xDirectInputA((IDirectInputA*)(*ppDI));

TBH what you are trying to do is more complicated than you think. The problem arises in what exactly you are trying to do. Are you trying to wrap IDirectInputA OR are you trying to completely re-implement it.

If you are trying to wrap it do the following:

IDirectInputA* pDI = NULL;
HRESULT hr = _DirectInputCreateA( hinst, dwVersion, &pDI, NULL );

Then create your derived class as follows:

class xDirectInputA : public IDirectInputA
    IDirectInputA* mpInternal;
    xDirectInputA( IDirectInputA* pInternal ) :
         mpInternal( pInternal )

    HRESULT CreateDevice( REFGUID rguid, IDirectInputDevice** ppDirectInputDevice, IUknown* pOuter )
        // Do what ever processing you need.
        return mpInternal->CreateDevice( rguid, ppDirectInputDevice, pOuter );

    // Implement other functions.

Now you pass your xDirectInputA pointer around instead of the normal pointer returned from DirectInputCreate. You can now intercept every message that goes through the class.

If you are trying to do your own full re-implementation it is a LOT more complicated. You are going to need to fully implement the COM object. You'll be best off putting a DInput.DLL alongside the executable that contains your implementation. All in though this is only something you should try if you REALLY know what you are doing.

If you wish to learn COM fully I suggest purchasing Essential COM by Don Box. Its a VERY helpful book.

I have a DLL which I am importing to the project as a type library using the Import Type Library functionality under Project in Delphi 6. I recently became curious about what the relationship between the _TLB.pas file and the DLL it was generated from are. Is the _TLB.pas file used in place of the library or only if I have my code interface with it? What other information would be good to know about how the code in the _TLB.pas works with the DLL it was generated from?

The .pas file is generated from the type library, which is typically contained within the COM DLL.

The .pas file defines the interface to the COM DLL. COM DLL's which come with embedded type libraries have self-describing interfaces. You still need documentation to understand what the interfaces and methods do, and how the parameters are used. But you don't need to write the boiler plate interface code yourself.

When a COM DLL has an embedded type library, you can create import units in your programming language of choice, not just Delphi.

If you want to know COM there is no better reference than Don Box's Essential COM, one of the finest computing books I have ever read.

I have started working with C++ recently and am not comfortable with Visual Studio Development Environment and also I do not have proper understanding of MFC, Win32, ATL, COM Terminologies.

From example point of view, I had taken a simple C++ program to see how it works with Visual Studio Environment and I was having some issues to get that code up and running.

I would like to request if someone could point me to some online resources/books where I can get more understanding about Visual Studio Development Environment from C++ perspective and get some knowledge about MFC, Win32, ATL, COM Terminologies than it would be really very helpful to me.

Note: I have checked MSDN library and some related Microsoft sites but when I see HOW DO I kind of video tutorials they are more from .Net/C#/ASP.Net perspective but I am looking for some online resource for C++/VC++ perspective.

The classic book about Win32 is presumably Petzold's. Petzold's book is I think (I've never read it) mostly about GUI programming; whereas the other classic/recommended Win32 book, which is Richter's, is about 'system' (non-GUI) programming.

For learning COM, perhaps Essential COM? Some reviewers praise it, but some others reviews say things like "not for beginners"; but it's how I learned COM, and I found it thorough, low-level, and detailed. It assumes you know C++ (not COM) already.

IMO you don't need books about MFC if you already know C++ and the Win32 API, in which case the reference libraries are sufficient. Alternatively, some people recommend an MFC book like Prosise's.

I've been reading Essential COM, it is a very good book, very instructive and simple to understand. Now I want to speed things up and implement a simple COM object, compile it into a .dll and finally use it from a client application.

I would really appreciate if anybody could show the most basic sample of how to do that?

I've been trying with this step by step but, besides founding some errors, I could not make it work. The reason for this is that I've created a simple Win32 application, I started coding the COM from scratch (as the step by step shows) and fails to compile/link (lot of errors), I must be forgetting some configuration or some includes in stdafx.h or whatever.

I'm working in Visual C++ with Microsoft Visual Studio .Net 2003

Thanks in advance!

One of the most friction-free ways is to use one of the wizard-generated solutions, and in particular the "ATL Project" wizard in VS 2008 (not sure about 2003). You just select "DLL" when asked the server type you want, and you're left with a very usable COM DLL skeleton where to fill in your code.

Tip: to add a new COM interface and coclass, the easiest way is to go to Class View, right-click on the project, and select Add->Class..., then select "ATL Simple Object" and answer the wizard questions.

EDIT: to answer Toto's additional question in the comments (how to create a client to use the freshly-created COM DLL), the answer is "it depends on the language", as you have an enormous choice here. You can use VB ("add reference"), C#/VB.NET ("add reference", COM tab), VBScript (WScript.CreateObject), and of course C++ too. In a nutshell, from a C++ client you need to include the server's IDL and link to the server's LIB file.

Ok, what am i doing wrong here? i'm trying to include a vbscript with a class inside this way:


set inc = createobject("script.runner")
inc.Include "class"
set x = new test
x.msg' here i get the error 'undefined class'!

REGISTERED .wsc file:

<?xml version="1.0"?>
<method name="Include">
<PARAMETER name="Script"/>
<script language="VBScript">
Sub Include(Script)
ExecuteGlobal(CreateObject("scripting.filesystemobject").OpenTextFile(Script & ".vbs", 1).Readall & VBNewLine)
End Sub


class test
public sub msg
msgbox "hi"
end sub
end class

I was thinking maybe i need to define it in the wsc file if i'm going to use classes or something? i don't know..

Thanks for any help!

VBscript's Execute(Global) and .COM are very different ways of re-using code. You shouldn't mix them.

A .wsc lets you create one object and use its methods and properties. Such a method (factory) may create and return another object. So if you add

<method name="mkTest">
Function mkTest()
  Set mkTest = New test
End Function

to your .wsc and

set x = inc.mkTest

to your .vbs, the whole rigmarole will 'work'.

You should think about your real world task, read a good book about .COM, and come up with a simple strategy that does not mix heterogeneous technologies (maybe the Sub Include()/ExecuteGlobal approach sketched here).