www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Newbie question: COM programming and linking to Windows libraries

reply Patrick Kristiansen <patrick.kristiansen gmail.com> writes:
Hi

I've been trying out D lately, and I really love it. I use the Tango library at
the moment, and I wanted to do some simple COM programming, which I'm also a
newbie at, just to get more acquainted with Windows programming in D.

What I want to do is relatively simple I think. I want to use the
IActiveDesktop COM interface to change the wallpaper of my desktop. So far I
have ported the definition of the interface to D and the different structs used
as arguments to the interface's methods. The porting went pretty easily,
although I haven't been able to test it yet (I'll return to that in a moment).
The standard Windows types (e.g. LPCTSTR, DWORD, etc.) are, as you probably
know, defined in tango.sys.win32.Types.

I looked at the samples that is included with the DMD compiler bundle
(dclient.d, dserver.d and chello.d) to see COM programming in D is done.
Apparently, one of the first things to do is call CoInitialize(...), and this
is where my problem arises.

CoInitialize is located in ole32.lib, but in the Tango distribution of DMD,
there is no ole32.lib included. I thought, since I have the Windows SDK (x64)
installed, that I could just link directly to the ole32.lib included there.

Now, this is probably obvious to some people - but not to me. Why doesn't this
work? Why does OPTLINK fail and tell me that the format of the .lib file is
wrong? Is it because Digital Mars compilers produce .lib files in a different
format? Is it because I have the 64 bit SDK installed, and DMD and optlink only
produce and consume 32 bit object files and libraries?

Please enlighten me ;-)

Thanks in advance.

-Patrick
Mar 11 2009
next sibling parent Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Wed, Mar 11, 2009 at 5:31 PM, Patrick Kristiansen
<patrick.kristiansen gmail.com> wrote:
  Apparently, one of the first things to do is call CoInitialize(...), and this
is where my problem arises.
That's funny, I've never had to call it when using DirectX interfaces. Maybe it's something peculiar to DirectX?
 CoInitialize is located in ole32.lib, but in the Tango distribution of DMD,
there is no ole32.lib included. I thought, since I have the Windows SDK (x64)
installed, that I could just link directly to the ole32.lib included there.

 Now, this is probably obvious to some people - but not to me. Why doesn't this
work? Why does OPTLINK fail and tell me that the format of the .lib file is
wrong? Is it because Digital Mars compilers produce .lib files in a different
format?
That's exactly the reason. DM uses the OMF format, an old object format that MS compilers used to generate before they switched to COFF. Of course they've been using COFF since something like VC5 or VC6, so none of the object files that MS distributes are compatible with DM compilers anymore. Also, DM compilers do only generate 32-bit objects and executables, though the object file format discrepancy has always been a problem. You should be able to generate an OMF import library for ole32 from the ole32.dll in windows\system32 (or wherever that is on Win64). You can use the DM implib utility (contained in the BUP here: http://ftp.digitalmars.com/bup.zip) to do so. Something like: implib /system ole32.lib ole32.dll should do it.
Mar 11 2009
prev sibling next sibling parent Daniel Keep <daniel.keep.lists gmail.com> writes:
Patrick Kristiansen wrote:
 ...
 
 Now, this is probably obvious to some people - but not to me. Why doesn't this
work? Why does OPTLINK fail and tell me that the format of the .lib file is
wrong? Is it because Digital Mars compilers produce .lib files in a different
format? Is it because I have the 64 bit SDK installed, and DMD and optlink only
produce and consume 32 bit object files and libraries?
 
 Please enlighten me ;-)
 
 Thanks in advance.
 
 -Patrick
The DM toolchain produces and consumes OMF object files, while I suspect the SDK uses COFF. Also, the toolchain is 32-bit, not 64-bit. There's a tool called implib which can generate a .lib file that DMD/OPTLINK can use. Documentation is here: <http://www.digitalmars.com/ctg/implib.html>. You can get it by going to <http://www.digitalmars.com/>, clicking on "Download Digital Mars C compiler", accept the agreement, and then scroll down to "Basic Utilities". -- Daniel
Mar 11 2009
prev sibling next sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Thu, 12 Mar 2009 00:31:33 +0300, Patrick Kristiansen
<patrick.kristiansen gmail.com> wrote:

 Hi

 I've been trying out D lately, and I really love it. I use the Tango  
 library at the moment, and I wanted to do some simple COM programming,  
 which I'm also a newbie at, just to get more acquainted with Windows  
 programming in D.

 What I want to do is relatively simple I think. I want to use the  
 IActiveDesktop COM interface to change the wallpaper of my desktop. So  
 far I have ported the definition of the interface to D and the different  
 structs used as arguments to the interface's methods. The porting went  
 pretty easily, although I haven't been able to test it yet (I'll return  
 to that in a moment). The standard Windows types (e.g. LPCTSTR, DWORD,  
 etc.) are, as you probably know, defined in tango.sys.win32.Types.

 I looked at the samples that is included with the DMD compiler bundle  
 (dclient.d, dserver.d and chello.d) to see COM programming in D is done.  
 Apparently, one of the first things to do is call CoInitialize(...), and  
 this is where my problem arises.

 CoInitialize is located in ole32.lib, but in the Tango distribution of  
 DMD, there is no ole32.lib included. I thought, since I have the Windows  
 SDK (x64) installed, that I could just link directly to the ole32.lib  
 included there.

 Now, this is probably obvious to some people - but not to me. Why  
 doesn't this work? Why does OPTLINK fail and tell me that the format of  
 the .lib file is wrong? Is it because Digital Mars compilers produce  
 .lib files in a different format? Is it because I have the 64 bit SDK  
 installed, and DMD and optlink only produce and consume 32 bit object  
 files and libraries?

 Please enlighten me ;-)

 Thanks in advance.

 -Patrick
You can simply download DMD distribution from digitalmars.com, it includes ole32.lib
Mar 11 2009
prev sibling next sibling parent reply jicman <cabrera_ _wrc.xerox.com> writes:
Patrick Kristiansen Wrote:

 Hi
 
 I've been trying out D lately, and I really love it. I use the Tango library
at the moment, and I wanted to do some simple COM programming, which I'm also a
newbie at, just to get more acquainted with Windows programming in D.
 
 What I want to do is relatively simple I think. I want to use the
IActiveDesktop COM interface to change the wallpaper of my desktop. So far I
have ported the definition of the interface to D and the different structs used
as arguments to the interface's methods. The porting went pretty easily,
although I haven't been able to test it yet (I'll return to that in a moment).
The standard Windows types (e.g. LPCTSTR, DWORD, etc.) are, as you probably
know, defined in tango.sys.win32.Types.
 
 I looked at the samples that is included with the DMD compiler bundle
(dclient.d, dserver.d and chello.d) to see COM programming in D is done.
Apparently, one of the first things to do is call CoInitialize(...), and this
is where my problem arises.
 
 CoInitialize is located in ole32.lib, but in the Tango distribution of DMD,
there is no ole32.lib included. I thought, since I have the Windows SDK (x64)
installed, that I could just link directly to the ole32.lib included there.
 
 Now, this is probably obvious to some people - but not to me. Why doesn't this
work? Why does OPTLINK fail and tell me that the format of the .lib file is
wrong? Is it because Digital Mars compilers produce .lib files in a different
format? Is it because I have the 64 bit SDK installed, and DMD and optlink only
produce and consume 32 bit object files and libraries?
 
 Please enlighten me ;-)
 
 Thanks in advance.
I have been able to use juno (http://www.dsource.org/projects/juno) and use the windows COM devices to connect to MS Office, Adobe Illustrator, Trados and a bunch of other windows apps very easily. jic
Mar 11 2009
parent Patrick Kristiansen <patrick.kristiansen gmail.com> writes:
jicman Wrote:

 Patrick Kristiansen Wrote:
 
 Hi
 
 I've been trying out D lately, and I really love it. I use the Tango library
at the moment, and I wanted to do some simple COM programming, which I'm also a
newbie at, just to get more acquainted with Windows programming in D.
 
 What I want to do is relatively simple I think. I want to use the
IActiveDesktop COM interface to change the wallpaper of my desktop. So far I
have ported the definition of the interface to D and the different structs used
as arguments to the interface's methods. The porting went pretty easily,
although I haven't been able to test it yet (I'll return to that in a moment).
The standard Windows types (e.g. LPCTSTR, DWORD, etc.) are, as you probably
know, defined in tango.sys.win32.Types.
 
 I looked at the samples that is included with the DMD compiler bundle
(dclient.d, dserver.d and chello.d) to see COM programming in D is done.
Apparently, one of the first things to do is call CoInitialize(...), and this
is where my problem arises.
 
 CoInitialize is located in ole32.lib, but in the Tango distribution of DMD,
there is no ole32.lib included. I thought, since I have the Windows SDK (x64)
installed, that I could just link directly to the ole32.lib included there.
 
 Now, this is probably obvious to some people - but not to me. Why doesn't this
work? Why does OPTLINK fail and tell me that the format of the .lib file is
wrong? Is it because Digital Mars compilers produce .lib files in a different
format? Is it because I have the 64 bit SDK installed, and DMD and optlink only
produce and consume 32 bit object files and libraries?
 
 Please enlighten me ;-)
 
 Thanks in advance.
I have been able to use juno (http://www.dsource.org/projects/juno) and use the windows COM devices to connect to MS Office, Adobe Illustrator, Trados and a bunch of other windows apps very easily. jic
Thanks for all your replies. I'll give it a try. -Patrick
Mar 12 2009
prev sibling parent reply Patrick Kristiansen <patrick.kristiansen.lists gmail.com> writes:
Patrick Kristiansen Wrote:

 Hi
 
 I've been trying out D lately, and I really love it. I use the Tango library
at the moment, and I wanted to do some simple COM programming, which I'm also a
newbie at, just to get more acquainted with Windows programming in D.
 
 What I want to do is relatively simple I think. I want to use the
IActiveDesktop COM interface to change the wallpaper of my desktop. So far I
have ported the definition of the interface to D and the different structs used
as arguments to the interface's methods. The porting went pretty easily,
although I haven't been able to test it yet (I'll return to that in a moment).
The standard Windows types (e.g. LPCTSTR, DWORD, etc.) are, as you probably
know, defined in tango.sys.win32.Types.
 
 I looked at the samples that is included with the DMD compiler bundle
(dclient.d, dserver.d and chello.d) to see COM programming in D is done.
Apparently, one of the first things to do is call CoInitialize(...), and this
is where my problem arises.
 
 CoInitialize is located in ole32.lib, but in the Tango distribution of DMD,
there is no ole32.lib included. I thought, since I have the Windows SDK (x64)
installed, that I could just link directly to the ole32.lib included there.
 
 Now, this is probably obvious to some people - but not to me. Why doesn't this
work? Why does OPTLINK fail and tell me that the format of the .lib file is
wrong? Is it because Digital Mars compilers produce .lib files in a different
format? Is it because I have the 64 bit SDK installed, and DMD and optlink only
produce and consume 32 bit object files and libraries?
 
 Please enlighten me ;-)
 
 Thanks in advance.
 
 -Patrick
Following the suggestions given by multiple people on this forum, I still run into trouble. Here is what I did. First I used implib to import the OMF library for ole32.dll. I am using Windows Vista x64, and I invoked implib like this: $> implib /s ole32.lib c:\windows\syswow64\ole32.dll Then I got a ole32.lib file as expected. The next step was to declare the function I want to use. For starters, I wanted to call CoInitialize(...). I defined it in D as such: extern( Windows ) HRESULT CoInitialize( LPVOID pvReserved ); I then called CoInitialize like this CoInitialize( null ) as Windows SDK docs says I should. Finally, I try to compile everything. I have two files and ole32.lib: $> dmd setwallp.d ActiveDesktop.d ole32.lib The compiler fails with the following error: setwallp.obj(setwallp) Error 42: Symbol Undefined _CoInitialize 4 --- errorlevel 1 Why? I have attached a ZIP file with all my source code. As mentioned, I am trying to do something relatively simple. If I was using Phobos, I could just use CoInitialize from there (std.c.windows.com), but I am using Tango, which doesn't appear to have it defined. I could also use a third-party library like Juno, but I don't want to do that for something as simple as this should be. I could also use the ole32.lib file that comes with DMC, but it seems to correspond to an old version of ole32.dll - not that it matters much. Is this inherently NOT simple to do? :-) Is it at all possible to do the way I want to, or should I use one of the other approaches I outlined myself? Hopefully, you have an answer for me. You have been very helpful alread. Best regards, Patrick
Mar 12 2009
parent Sergey Gromov <snake.scaly gmail.com> writes:
Thu, 12 Mar 2009 17:12:41 -0400, Patrick Kristiansen wrote:

 The compiler fails with the following error:
 
      setwallp.obj(setwallp)
       Error 42: Symbol Undefined _CoInitialize 4
      --- errorlevel 1
The implib doesn't produce acceptable results for Windows system DLLs. It does create a library, but functions in that library are mangled using either Pascal (default) or cdecl (/s switch) naming convention. That is, either plain function name, or name with an underscore prepended, respectively. Windows uses stdcall convention. Mangled names in this convention include size of function arguments, the 4 part in your example. The information in DLL is insufficient to gather this sort of information so implib can't help here even in theory. If you have a COFF lib from SDK the best you can do is to use coffimplib instead: http://www.digitalmars.com/ctg/coffimplib.html available from Digital Mars FTP: ftp://ftp.digitalmars.com/ This tool converts a COFF library into an OMF one, preserving any required information and immediately usable with DMD.
Mar 12 2009