From: Chris W. <ch...@qw...> - 2006-12-04 22:26:50
|
Hi all, I'm sorry if this has been covered in previous posts. I'm afraid I'm still a bit lost with the issues relating to linking MinGW code with Windows DLLs. I'm trying to use the Microsoft Volume Shadow Copy Service (VSS) from MinGW, for a GPL application, without needing my users to download the VSS API (license encumbered and not GPL compatible). Therefore, I would like to add support for this service to MinGW and to my application, which already compiles with MinGW and MSVC, and retain the ability to compile with both. Most of the VSS API is COM, and is covered by MSDN, so I think I can write a freely distributable set of headers for that part using only MSDN as a source. I've never done this before, so I could use some pointers to writing COM headers for MinGW. However, my first problem is that one function from this DLL needs to be called to get the first COM interface. That function, CreateVssBackupComponents [http://msdn2.microsoft.com/en-gb/library/aa381517.aspx] appears to have been compiled by Microsoft using MSVC C++ name mangling, even though it is not an object method, just a function, and nor is it overloaded. Objdump on the VSSAPI.DLL included in Windows XP shows: /tmp/vssapi.dll: file format efi-app-ia32 /tmp/vssapi.dll architecture: i386, flags 0x0000010b: HAS_RELOC, EXEC_P, HAS_DEBUG, D_PAGED [...] Ordinal/Name Pointer] Table [...] [ 11] ?CreateVssBackupComponents@@YGJPAPAVIVssBackupComponents@@@Z It looks like it will be very tricky to link directly to this function from MinGW. I tried to use the following definition: HRESULT __stdcall CreateVssBackupComponents(IVssBackupComponents** ppBackup) __attribute__ ((alias ("CreateVssBackupComponents@@YGJPAPAVIVssBackupComponents@@@Z"))); However, it misses the initial question mark (?), since g++ complains about invalid junk in the assembler if I include it, and g++ still complains about a missing symbol at link time, having added a prefix underscore to the symbol name, even if I use the -fno-leading-underscore option to g++. I know that name mangling is only one issue related to calling C++ methods from one compiler in another, but this is not a method, just a function compiled by Microsoft without extern "C", so I assume that the other problems don't apply here? I'm pretty much at a loss how to call this function from MinGW. The only way I can think of is to write a small wrapper library that I compile with MSVC, that re-exports this function using extern "C" under a different name, and link my MinGW code with this wrapper library. However, this is really ugly because it means I have to call the function with a different name when using MinGW, and use #define magic to achieve compilation with both MinGW and MSVC. Can anyone see another option? I have read the MinGWiki pages: * http://www.mingw.org/MinGWiki/index.php/MSVC-MinGW-DLL * http://www.mingw.org/MinGWiki/index.php/MixObjects However, I'm still lost, since the examples seem tuned towards building DLLs with MinGW that can be linked to MSVC applications, and what I want to do is the reverse. I tried to use dlltool to re-export the symbols from the DLL in an import library, but 'dlltool --export-all-symbols' on the DLL tells me that no symbols were found, and creates an import library with no useful symbols. I haven't tried pexports yet, and I don't know if it can help. Can anyone offer me any advice? Thanks in advance for your help. Cheers, Chris. -- _ ___ __ _ / __/ / ,__(_)_ | Chris Wilson <0000 at qwirx.com> - Cambs UK | / (_/ ,\/ _/ /_ \ | Security/C/C++/Java/Perl/SQL/HTML Developer | \ _/_/_/_//_/___/ | We are GNU-free your mind-and your software | |
From: Greg C. <chi...@co...> - 2006-12-05 00:05:53
|
On 2006-12-4 22:26 UTC, Chris Wilson wrote: [snip reason for needing to call CreateVssBackupComponents(), which seemingly should have been 'extern "C"' but isn't; assuming that's correct...] > I'm pretty much at a loss how to call this function from MinGW. The only > way I can think of is to write a small wrapper library that I compile with > MSVC, that re-exports this function using extern "C" under a different > name, and link my MinGW code with this wrapper library. Sounds like a good idea, and perhaps the best idea. > However, this is > really ugly because it means I have to call the function with a different > name when using MinGW, and use #define magic to achieve compilation with > both MinGW and MSVC. Maybe the ugliness can be addressed separately: - Call your wrapper, say, DoCreateVssBackupComponents(). - Use your wrapper library, with that function name, for both gcc and msvc. Or you could add a wrapper for your wrapper: extern "C" inline void* CreateVssBackupComponents() {return InternalNameOfWrappedFunction();} but I guess that just moves the ugliness around. I'd be tempted to live with the macro ugliness. Probably you do already: e.g., MessageBox() isn't a function, it's a macro that refers to MessageBoxA() or MessageBoxW(). > I tried to use dlltool to re-export the symbols from the DLL in an import > library, but 'dlltool --export-all-symbols' on the DLL tells me that no > symbols were found, and creates an import library with no useful symbols. > I haven't tried pexports yet, and I don't know if it can help. Many years ago, I had to interface to a third-party dll for which I simply couldn't manage to build an import library that worked, despite much effort. So I fell back on what I guess is the most elementary, brute-force technique, and wrote a '.def' file by hand--and that worked. NAME 'WHATEVER' EXETYPE WINDOWS IMPORTS _WhateverNameYouWant =GOOFY_DLL.GoofyInternalName [Snip hundreds of other functions...but you want only one] That was the magic glue that let me call an msvc-built dll from an application built with a different proprietary compiler. Later, I rebuilt my application with gcc, creating a gcc import library this way: libGOOFY_DLL.a: $(some_directory)/GOOFY_DLL.dll GOOFY_DLL.def $(DLLTOOL) \ --dllname GOOFY_DLL.dll \ --input-def $(src_dir)/GOOFY_DLL.def \ --output-lib libGOOFY_DLL.a and that worked, too. My problem was with a C dll, and I don't know whether a C++ dll would be more difficult. And I didn't have msvc, so writing a wrapper library with msvc wasn't an option. But if you already have msvc, then the wrapper approach seems safe, straightforward, and robust; perhaps you've already reduced the mess to a minimum with that idea. |
From: Chris W. <ch...@qw...> - 2006-12-05 00:17:10
|
Hi Greg, On Tue, 5 Dec 2006, Greg Chicares wrote: >> I'm pretty much at a loss how to call this function from MinGW. The only >> way I can think of is to write a small wrapper library that I compile with >> MSVC, that re-exports this function using extern "C" under a different >> name, and link my MinGW code with this wrapper library. > > Sounds like a good idea, and perhaps the best idea. Do you have any idea whether distributing such a wrapper library (compiled with MSVC Express 2005) under the GPL is allowed by Microsoft? I think it might not be, since it may contain Microsoft proprietary object code (I hope not, but I'm not sure). > NAME 'WHATEVER' > EXETYPE WINDOWS > IMPORTS > _WhateverNameYouWant =GOOFY_DLL.GoofyInternalName I tried to create a .def file, starting with either: LIBRARY vssapi or NAME 'vssapi' but in both cases, cygwin's dlltool tells me: dlltool: Syntax error in def file vssapi.def:1 I don't have a definitive reference for DEF file syntax that's supported by dlltool, so I'm stuck here :-(. Can anyone help? Cheers, Chris. -- _ ___ __ _ / __/ / ,__(_)_ | Chris Wilson <0000 at qwirx.com> - Cambs UK | / (_/ ,\/ _/ /_ \ | Security/C/C++/Java/Perl/SQL/HTML Developer | \ _/_/_/_//_/___/ | We are GNU-free your mind-and your software | |
From: Greg C. <chi...@co...> - 2006-12-05 01:06:38
Attachments:
lmi.def.tar.bz2
|
On 2006-12-5 0:17 UTC, Chris Wilson wrote: > On Tue, 5 Dec 2006, Greg Chicares wrote: > >> NAME 'WHATEVER' >> EXETYPE WINDOWS >> IMPORTS >> _WhateverNameYouWant =GOOFY_DLL.GoofyInternalName > > I tried to create a .def file, starting with either: > > LIBRARY vssapi > > or > > NAME 'vssapi' > > but in both cases, cygwin's dlltool tells me: > > dlltool: Syntax error in def file vssapi.def:1 > > I don't have a definitive reference for DEF file syntax that's supported > by dlltool, so I'm stuck here :-(. Can anyone help? Attached is a skeletal '.def' file that actually does nothing, but should have valid syntax. I think it was created in the days of steam-powered computers by some application generator; it's from an ancient project and certainly ought to be valid. I send it as an archive in order to make sure you have an exact copy--who knows, LF vs. CR/LF might matter. If this gives a syntax error, then maybe the dlltool command isn't quite right. Please show the full command line to produce that error, either with my '.def' file or with yours. I seem to remember having a similar problem years ago, and maybe seeing your command will jog my memory. |
From: Chris W. <ch...@qw...> - 2006-12-05 21:13:23
|
Hi Greg, On Tue, 5 Dec 2006, Greg Chicares wrote: >> but in both cases, cygwin's dlltool tells me: >> >> dlltool: Syntax error in def file vssapi.def:1 >> >> I don't have a definitive reference for DEF file syntax that's supported >> by dlltool, so I'm stuck here :-(. Can anyone help? > > Attached is a skeletal '.def' file that actually does nothing, > but should have valid syntax. I think it was created in the > days of steam-powered computers by some application generator; > it's from an ancient project and certainly ought to be valid. > I send it as an archive in order to make sure you have an > exact copy--who knows, LF vs. CR/LF might matter. The command "dlltool -d lmi.def" on that file gives me: dlltool: Syntax error in def file lmi.def:15 I don't think there is anything on line 15! However, I did manage to generate a DEF file that works with dlltool with pexports. Using this, I can link to and call CreateVssBackupComponents in MSVC. Now I'm stuck because MSDN is lying - it says it lists the methods of IVssBackupComponents in vtable order, but actually they are not (I peeked at the VSS SDK to confirm this). Without knowing the order, I cannot write a header to define the interface. I don't know how to figure out which order they are in without trial and error, or resorting to the VSS SDK. I guess that in either case, I would not be able to publish a free header for use in MinGW based on such information. Can anyone see another way to deduce the order of methods in the vtable? Cheers, Chris. -- _ ___ __ _ / __/ / ,__(_)_ | Chris Wilson <0000 at qwirx.com> - Cambs UK | / (_/ ,\/ _/ /_ \ | Security/C/C++/Java/Perl/SQL/HTML Developer | \ _/_/_/_//_/___/ | We are GNU-free your mind-and your software | |
From: Keith M. <kei...@us...> - 2006-12-06 05:58:51
|
On Tuesday 05 December 2006 21:13, Chris Wilson wrote: > I don't know how to figure out which order they are in without trial and > error, or resorting to the VSS SDK. I guess that in either case, I would > not be able to publish a free header for use in MinGW based on such > information. Can anyone see another way to deduce the order of methods in > the vtable? I would have thought, if you can determine it *without* resorting to a study of the VSS SDK headers, by a purely trial and error approach, then that would be a perfectly legitimate way to derive the information you need for a free header; it is, after all, the approach we adopt to fill in the blanks, when the MSDN info is either incomplete, or inaccurate. I do wonder if the difference in order you see, wrt what MSDN leads you to expect, may be because the vtable structure, and hence ordering, may very well differ between MSVC and MinGW? Regards, Keith. |
From: Chris W. <ch...@qw...> - 2007-01-04 01:02:30
|
Hi Keith, On Wed, 6 Dec 2006, Keith Marshall wrote: > On Tuesday 05 December 2006 21:13, Chris Wilson wrote: >> I don't know how to figure out which order they are in without trial and >> error, or resorting to the VSS SDK. I guess that in either case, I would >> not be able to publish a free header for use in MinGW based on such >> information. Can anyone see another way to deduce the order of methods in >> the vtable? > > I would have thought, if you can determine it *without* resorting to a > study of the VSS SDK headers, by a purely trial and error approach, then > that would be a perfectly legitimate way to derive the information you > need for a free header; it is, after all, the approach we adopt to fill > in the blanks, when the MSDN info is either incomplete, or inaccurate. That's interesting. I thought that such trial and error approaches were "reverse engineering" and therefore not allowed? > I do wonder if the difference in order you see, wrt what MSDN leads you > to expect, may be because the vtable structure, and hence ordering, may > very well differ between MSVC and MinGW? I wish it were, but I'm afraid not. The methods listed "in vtable order" on the MSDN page are clearly in alphabetical order, and I peeked at the headers in the SDK, and they clearly are not. I wonder how anybody can trust anything that they read in MSDN? Cheers, Chris. -- _ ___ __ _ / __/ / ,__(_)_ | Chris Wilson <0000 at qwirx.com> - Cambs UK | / (_/ ,\/ _/ /_ \ | Security/C/C++/Java/Perl/SQL/HTML Developer | \ _/_/_/_//_/___/ | We are GNU-free your mind-and your software | |
From: James S. <jam...@op...> - 2007-01-04 01:18:07
|
On Thu, 2007-01-04 at 01:02 +0000, Chris Wilson wrote: > Hi Keith, > > On Wed, 6 Dec 2006, Keith Marshall wrote: > > I do wonder if the difference in order you see, wrt what MSDN leads you > > to expect, may be because the vtable structure, and hence ordering, may > > very well differ between MSVC and MinGW? > > I wish it were, but I'm afraid not. The methods listed "in vtable order" > on the MSDN page are clearly in alphabetical order, and I peeked at the > headers in the SDK, and they clearly are not. > > I wonder how anybody can trust anything that they read in MSDN? I look at the information as a kind of ... rough guide ;-) (sorry for butting in and thanks for the laughs.) Regards, James. |
From: Keith M. <kei...@to...> - 2007-01-04 10:54:21
|
Chris Wilson wrote, quoting me: >>> I don't know how to figure out which order they are in without trial and >>> error, or resorting to the VSS SDK. I guess that in either case, I would >>> not be able to publish a free header for use in MinGW based on such >>> information. Can anyone see another way to deduce the order of methods in >>> the vtable? >> >> I would have thought, if you can determine it *without* resorting to a >> study of the VSS SDK headers, by a purely trial and error approach, then >> that would be a perfectly legitimate way to derive the information you >> need for a free header; it is, after all, the approach we adopt to fill >> in the blanks, when the MSDN info is either incomplete, or inaccurate. > > That's interesting. I thought that such trial and error approaches were > "reverse engineering" and therefore not allowed? With the usual caveat that IANAL, that is not my understanding, at least in terms of United Kingdom law. This was all summarised in a recent issue of the UK `Linux Format' magazine, in an article which *was* written by a legal expert; my layman's understanding of that article leads me to the conclusion that:-- 1) When I purchase a software license from any software vendor, I *must* be granted a `fair use' entitlement to make that software interoperate with *any* other software I am legally entitled to deploy. 2) If the software vendor attempts to deny me that `fair use' right, by means of any wording in a License Agreement, then such clause is not legally binding, and in fact, renders the *entire* agreement legally invalid, and hence void. 3) If the software vendor refuses to publish, or otherwise disclose to me, such information as I require to achieve (1), then I am entitled under the `fair use' requirement to deduce it for myself; thus any trial and error approach I adopt to achieve that objective *must* be legitimate. Ok, so I've purchased a license to deploy Win2K on my desktop PC, (and I assume you have too -- your's may be for a later version, but that isn't pertinent to this discussion, and in any case, it isn't my responsibility to police your abuse of Microsoft licenses, in case you haven't). I also wish to use MinGW, as a software development tool, and I have a `fair use' right to make that work, on my Win2K platform. On MSDN, Microsoft publish the details of the API calls I need, to achieve interoperability with the Win2K core libraries; they don't always publish the appropriate values for all of the manifest constants specified for use in those calls, so I'm forced to deduce them experimentally. I conduct a scientific experiment, and I publish my results; I believe that is no more than `fair use'. (Besides, Microsoft should have documented the API properly in the first place). Do note that I am *not* advocating inspection of proprietary SDK headers, nor of `brute force' abuse of MSVC to simply `printf' the values of manifest constants it has compiled -- I don't believe that to be a valid experimental technique, and I will not accept patches based on this methodology. Also note that your admission that you have inspected the SDK headers leads me to conclude that any experimentally obtained data you provide may be tainted by knowledge you've gleaned from such inspection. If you want to contribute to MinGW, then please avoid inspection of proprietary Microsoft headers, from any source which does not grant you the right to verbatim reproduction. Regards, Keith. |