I'm having a bit of an argument with the IFile class and was wondering if
anyone had any suggestions? I've got an IFile (IDispatch) object representing a File and want to find the file's size. IFile has a #size message that looks good but can't be used as the superclasses existing #size method breaks the dnu resend and always answers 16 :-< Q1 Other than #asImplType (see Q3) is there a built in way of getting round this? Q2. Is there a way of changing an attributes name when the class is generated - renaming Size to FileSize for example? In the development environment I can get round the problem by sending #asImplType to the IDispatch object. When I deploy this doesn't seem to work and I'm not sure why. I tried not stripping some classes but it didn't seem to help - I may need to do more?. Q3 Is there a way of getting #asImplType to work in a deployed app? I've currently got around it in an "interesting" way (implemented IDispatch>>size which throws a dnu) but it looks a bit fragile :-) -- Ian Use the Reply-To address to contact me. Mail sent to the From address is ignored. |
Ian,
IFile? I don't appear to have that one. Did you generate it? If it is part of the base, where is it? Maybe I simply uninstalled something. I realize that there is danger in applying Smalltalk experience to Automation interfaces, but is IFile a file, a stream or both? If the two are separate concepts, perhaps the other (file or stream) would do what you want? > In the development environment I can get round the problem by sending > #asImplType to the IDispatch object. When I deploy this doesn't seem to > work and I'm not sure why. I tried not stripping some classes but it didn't > seem to help - I may need to do more?. > > Q3 Is there a way of getting #asImplType to work in a deployed app? My suspicion is that packages are being stripped. Adding manual prerequisites might fix it. In general, Lagoon will sometimes strip a package even though your code depends on things contained in the package. I am not sure whether the problem is in the stripper or in package dependencies. Have a good one, Bill -- Wilhelm K. Schwab, Ph.D. [hidden email] |
Bill,
> IFile? I don't appear to have that one. Did you generate it? If it > is part of the base, where is it? Maybe I simply uninstalled > something. Oops, sorry, I should have mentioned that bit. I use it in a number of packages and forgot that it's not part of the base. It's all to do with the Windows Scripting COM object. Once generated you gain some extra functionality over the existing File implementation ... tlb := AXTypeLibraryAnalyzer open: 'scrrun.dll'. tlb prefix: ''. tlb generateInterfaceWrappers. You can then open a fileSystem using ... fileSystem := IFileSystem createObject: 'Scripting.FileSystemObject'. and use fileSystem to access/create/delete folders and files. > My suspicion is that packages are being stripped. Adding manual > prerequisites might fix it. In general, Lagoon will sometimes strip a > package even though your code depends on things contained in the > package. I am not sure whether the problem is in the stripper or in > package dependencies. I remembered that I got around this in the past by turning off _all_ stripping when I deployed a package using IFileSystem. It's probably overkill (!) but I have vague recollections of spending too much time trying to sort out why deployed packages wouldn't work. -- Ian Use the Reply-To address to contact me. Mail sent to the From address is ignored. |
Ian,
> I remembered that I got around this in the past by turning off _all_ > stripping when I deployed a package using IFileSystem. It's probably > overkill (!) but I have vague recollections of spending too much time trying > to sort out why deployed packages wouldn't work. I have resorted to (almost) that extreme in one app that has real potential to break at random, and the risk is not worth saving a couple of megabytes in exe size for something that runs on servers. Otherwise, I find that stripping problems tend to present only on major releases, and are usually the result of improvement in stripping, hence the end product is smaller executables. It would be nice to have something that sets crash dump and any other logging options, to make it simple to configure end users' machines. AFAIK, the defaults create a file named exeName.errors, so you should be able to get good information about why a program broke. That's all the more true on your development machine. Have a good one, Bill -- Wilhelm K. Schwab, Ph.D. [hidden email] |
Bill,
> It would be nice to have something that sets crash dump and any other > logging options, to make it simple to configure end users' machines. > AFAIK, the defaults create a file named exeName.errors, so you should > be able to get good information about why a program broke. In this case the program doesn't actually break - it just doesn't work as expected :-( The code in question is ... anIDispatch asImplType size where anIDispatch is wrapping an IFile instance. In the development environment this works as the #asImplType answers the underlying IFile and that responds to #size with the file's size. In an deployed app #asImplType answers self (see IDispatch>>asImplType for why) which always responds to #size with 16. FWIW, my workaround "hack" seems not to cause any problems so I'll probably run with that for the moment. -- Ian Use the Reply-To address to contact me. Mail sent to the From address is ignored. |
In reply to this post by Ian Bartholomew-19
I wrote:
> I've got an IFile (IDispatch) object representing a File and want to > find the file's size. IFile has a #size message that looks good but > can't be used as the superclasses existing #size method breaks the > dnu resend and always answers 16 :-< FWIW, in the end it turned out to be a relatively simple stripping problem. In the failing app I was getting all the files at once - (anIFileSystem getFolder: 'c:\') files contents but in a different (working) app I was getting the files one at a time - aFileSystem getFile: 'c:\whatever' It turns out that the first method ends up with no references to IFile so the class is stripped. The second does retain an IFile reference so IFile is not stripped and everything ends up working. Sorry for all the wasted bandwidth :-) -- Ian Use the Reply-To address to contact me. Mail sent to the From address is ignored. |
In reply to this post by Ian Bartholomew-19
Ian
"Ian Bartholomew" <[hidden email]> wrote in message news:c4ll7p$2jsliv$[hidden email]... [...] > The code in question is ... > > anIDispatch asImplType size > > where anIDispatch is wrapping an IFile instance. In the development [...] FWIW, if you know you should always get an instance of IFile, you can do: anIFile := anIDispatch queryInterface: IFile. Then you have an explicit reference to the class you don't want stripped and you always get either the class you expect or nil. I've had to do that in some cases where #asImplType doesn't always return what you need, or there are no other references to the class I expect it to return. If the IDispatch instance doesn't support the interface you query, it just returns nil (rather than raising an error). HTH, Don |
Don,
> anIFile := anIDispatch queryInterface: IFile. Thanks for that. It seems to work perfectly in my deployed app and means I can avoid a bit of slightly obscure code. -- Ian Use the Reply-To address to contact me. Mail sent to the From address is ignored. |
In reply to this post by Don Rylander-3
"Don Rylander" <[hidden email]> wrote in
message news:c4ub0m$2mkune$[hidden email]... > Ian > "Ian Bartholomew" <[hidden email]> wrote in message > news:c4ll7p$2jsliv$[hidden email]... > [...] > > The code in question is ... > > > > anIDispatch asImplType size > > > > where anIDispatch is wrapping an IFile instance. In the development > [...] > > FWIW, if you know you should always get an instance of IFile, you can do: > > anIFile := anIDispatch queryInterface: IFile. > > Then you have an explicit reference to the class you don't want stripped > you always get either the class you expect or nil. Yes, that is what one should do. #asImplType is intended for use in generic applications or services that want to return the most specific interface available to the caller. This is dependent upon (a) the underlying object providing the type information necessary to determine the target interface (e.g. it implements IProvideClassInfo), and (b) there being a wrapper class defined for that interface in Dolphin. >...I've had to do that in > some cases where #asImplType doesn't always return what you need, or there > are no other references to the class I expect it to return. Exactly. There is no way for the Lagoon Stripper to know what class will be returned here based on a static analysis, so it is necessary to take other steps to preserve any interface classes that may be needed. Contrary to an assertion elsewhere in this thread, it is simply not true to say that "in general" Lagoon will strip required packages, or that there is some kind of problem here. It will only remove packages that are not in the prerequisites tree of the root package. This is exactly the set of packages that one can view in the package browsers dependency tree. The automatic package dependency mechanism is based purely on tracing global object references. In Smalltalk it is not practical to determine dependencies on-the-fly for specific methods, for the obvious reason that there is insufficient type information accessible without excessive computation. Therefore it is possible that a package containing a loose method that is required may not be detected automatically, and consequently a required method may get removed when its owning package is uninstalled. It should be no great surprise that this can occur, but it can be a source of surprises in practice since one may not be aware that the dependency existed. If/when one is aware, then the facility to add manual prerequisites should be employed. Dolphin 6 will add tools that will make it easier to perform more static analysis of one's deployed applications; for example one can display a list of the selectors that are not implemented in a selected package and its prerequisites. This is useful in determining in advance whether manual prerequisites might be required, although this is not foolproof since it will only help find potentially missing methods that have unique selectors. It also doesn't take into account the special actions of the stripper in removing certain categories of methods, such as development methods. One can also use the manifest from the new deployment log to "constrain" a browser to see only those classes and methods in a deployed application. This shows what really remains, and can be very enlightening. Its worth remembering, also, that there are two fundamental sorts of image stripping performed by Lagoon. Firstly there is the removal of complete packages. This judgement is based purely on the package dependency mechanism, so as I say if one's package dependencies are correct then it *will not* remove packages that are required. The automatic dependencies will be correct in all cases that the dependency is visible to the prerequisite tracing mechanism as I described above. A great way to determine if the dependencies are correct, is to save out packages, and then load only the root package (i.e. the application itself) into a fresh image. One can then test that the application works correctly - be careful, however, that loading any test packages you may need isn't bringing in extra stuff that makes the tests work!. The other sort of stripping is the traditional Smalltalk image stripping based on traversing the dependency graph of references to globals and potential message sends. This is safer, in that its judgement of a potential dependency is much more conservative. As an example if you tend to write methods with the same selectors which are actually unrelated, then the standard stripping mechanism will not be able to determine which of the methods are actually needed, and so it will have to retain all those with the same selector. Package based stripping ignores messages altogether, so it can be less safe, although typically it is not because invisible package dependencies are not that common in practice, and where they occur one often uncovers them during development on loading packages and finding pieces are missing. Because package based stripping is less conservative, it is considerably more effective at removing classes and methods that are not needed. In this case (where there are no references to a class at all) it will be removed by even the more conservative of the stripping mechanisms, so it is necessary to create a reference to it for #asImplType to work, or do (what amounts to) an explicit cast. >...If the > IDispatch instance doesn't support the interface you query, it just returns > nil (rather than raising an error). Which is because it is not an error to ask for an interface that a component does not implement. The beauty of COM's QueryInterface is that it allows for dynamic discovery of the capabilities of an object, and typically this might involve asking for interfaces that only the most functional objects will implement, with progressive fallback. COM defines the error code E_NOINTERFACE as the HRESULT code returned for "I don't implement that interface", but in my view it should never really have been an error code. Typically the COM bindings of OO languages and libraries map error HRESULT codes to exceptions, but then have to treat the E_NOINTERFACE returned from QueryInteface() as a special case and return that languages representation of a null pointer. Regards Blair |
Blair,
> Contrary to an assertion elsewhere in this thread, it is simply not true to > say that "in general" Lagoon will strip required packages, or that there is > some kind of problem here. It will only remove packages that are not in the > prerequisites tree of the root package. This is exactly the set of packages > that one can view in the package browsers dependency tree. With respect, I've encountered this kind of thing too many times for it to be an accident. Whether or not it is technically a defect in Dolphin, it is most certainly something that I expect other users to encounter. Ian, as a long-time friend and respected collegue, deserves to benefit from my experience. Further, I was trying to help you by encouraging other uses to "keep trying" rather than giving up on stripping. Have a good one, Bill -- Wilhelm K. Schwab, Ph.D. [hidden email] |
Free forum by Nabble | Edit this page |