digitalmars.D.learn - Newbie question: COM programming and linking to Windows libraries
- Patrick Kristiansen (9/9) Mar 11 2009 Hi
- Jarrett Billingsley (17/20) Mar 11 2009 That's funny, I've never had to call it when using DirectX interfaces.
- Daniel Keep (10/19) Mar 11 2009 The DM toolchain produces and consumes OMF object files, while I suspect
- Denis Koroskin (2/31) Mar 11 2009 You can simply download DMD distribution from digitalmars.com, it includ...
- jicman (3/18) Mar 11 2009 I have been able to use juno (http://www.dsource.org/projects/juno) and ...
- Patrick Kristiansen (3/24) Mar 12 2009 Thanks for all your replies. I'll give it a try.
- Patrick Kristiansen (21/38) Mar 12 2009 Following the suggestions given by multiple people on this forum, I stil...
- Sergey Gromov (17/22) Mar 12 2009 The implib doesn't produce acceptable results for Windows system DLLs.
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
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
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. -PatrickThe 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
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. -PatrickYou can simply download DMD distribution from digitalmars.com, it includes ole32.lib
Mar 11 2009
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
jicman Wrote:Patrick Kristiansen Wrote:Thanks for all your replies. I'll give it a try. -PatrickHi 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 12 2009
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. -PatrickFollowing 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
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 1The 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