Experiments in early binding com object with D.

Vinod K Chandran kcvinu82 at gmail.com
Mon Nov 3 16:51:25 UTC 2025


Hi all,
I was worrying that there is no com support except the basic 
building blocks like IUnknown and siblings. I know there is a com 
library in Adam's arsd. But I couldn't successfully use that. 
When I first tried Adam's library, I dreamed to write a com 
client in D one day. When time permitted, I slowly collected 
information about com and gradually made a confidence to start 
with early binding. I want to make my library high performance, 
so I choose early binding path.

There is a c++ example in [this 
link](https://jacobfilipp.com/DrDobbs/articles/CUJ/1998/9810/brill/brill.htm) which shows early binding to a known com server. But in that article, the author shows how to work with unknown servers using an IDL file.

So I collected the IDL file of MS Word and wrote a sample 
interface in D like this -
```d
interface IWordApp : IDispatch
{
     HRESULT getApplication(IDispatch** prop);
     HRESULT getCreator(int* prop);
     HRESULT getParent(IDispatch** prop);
     ....
     HRESULT getUserName(BSTR* prop);
     HRESULT setUserName2( BSTR prop);
}
```
Then tried to print the `Application.UserName` with this code.
```d
void getWordEarlyBinding() {
     const IID iid = {0x00020970, 0x0000, 0x0000,
                     [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x46]};
     const GUID clsid = {0x000209FF, 0x0000, 0x0000,
          [0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46]};


     IWordApp word;
     auto hr1 = CoInitializeEx(null, COINIT_APARTMENTTHREADED );
     auto cci_res = CoCreateInstance(&clsid, null,
                                         CLSCTX_LOCAL_SERVER,
                                         &iid, cast(void**)&word);

     if (FAILED(cci_res)) {
         writeln("CoCreateInstance failed for Word.Application");
     }
     scope(exit) word.Release();
     BSTR bstrUserName = null;
     auto hr = word.getUserName(&bstrUserName);
     scope(exit) SysFreeString(bstrUserName);
     if (SUCCEEDED(hr)) {
         writefln("Word User Name BSTR: %s", 
bstrUserName.to!string  );
     } else {
         writeln("Failed to get UserName property.");
     }

     CoUninitialize();
}
```
And this code worked. It just printed my user name on console. Is 
this approach safe ? Converting the IDL file entries to D 
interface is a herculean task. The article I said earlier shows a 
method to compile the IDL file with `midl.exe` and generate 
header file & tlb file. But I couldn't create that. So, either 
with the help of any AI tool, or a python script, I think we can 
convert the IDL file to a proper D interface. Or is there any 
better ways ? Let's discuss the possibilities of this.
Vinod Chandran.


More information about the Digitalmars-d-learn mailing list