Page 2 of 5
XIDE Support for migration
Posted: Mon Jul 24, 2017 4:02 am
by wriedmann
I have now completed the first version of my PDF document about the migration of my basic library to X#.
You can find it here:
https://www.riedmann.it/download/wlib2_to_xs.pdf
I will try to keep it updated.
Wolfgang
XIDE Support for migration
Posted: Mon Jul 24, 2017 11:51 am
by markus.lorenzi@dvbern.ch
Hi Wolfgang
congratulations for this great document. This will help a lot of us guys too.
Markus
XIDE Support for migration
Posted: Mon Jul 24, 2017 11:58 am
by wriedmann
Hi Markus,
Thank you!
"gut Ding braucht gut Weile" - unfortunately it took a lot of time to write it because I added some backgrounds too (it was a suggestion by Chris).
And this document will be enhanced in the next days and weeks - I have several things to add from my other libraries (and have several problems yet to fix).
Therefore I don't added this document to my message, but put it on my webserver, so I can replace it every time I need to add or change something.
Wolfgang
XIDE Support for migration
Posted: Mon Jul 24, 2017 1:54 pm
by Chris
Hi Wolfgang,
Thank you very much! This is great, showing various ways to overcome several incompatibilities between the VO and .Net world. Guys, thanks a lot for all your effort in doing this, it will help others a lot!
Some comments:
- MCompile in VO returns the compiled version of the code in a STRING variable, sort of as a binary buffer. This wouldn't work in .Net, instead the return type in the vulcan implementation is simply CODEBLOCK.
- I think Don did not implement the Buffer() function because this is very commonly used in code that uses the return string as an 8 bit binary buffer to be used with Win32 API functions. It would have been possible to define the Buffer(dwSize) function just so that it returns Space(dwSize), but since strings are unicode in .Net, this would result to a buffer double the size of the same code running in VO, and not to mention other potential issues when using a string var as binary buffer in .Net. So maybe it is a good idea to not implement Buffer() in X# either, thus prompting the user to review and adjust the code accordingly.
- My fault, when you asked me about the GC, I thought you were talking about RegisterAxit(), but I see in your VO code you are using _RegisterExit(). This registers "clean up" functions to be called on application exit and as the error message says, you can implement it in .Net by using such code:
AppDomain.CurrentDomain:ProcessExit += AxitGlobal
FUNCTION AxitGlobal(o AS OBJECT , e AS EventArgs) AS VOID
...
but from what I see in your code, you use those to keep the garbage collector of VO happy be NULLifying yourself several objects before exiting, while normally in .Net this is not needed. But I see you are also closing some DBServers in the Exit functions, would be better to do that also in the X# version of your code, close them manually than wait for them to be auto-closed when the app exits.
- It is very nice that you show how to use extension methods for "external" code added to the SDK classes in VO, together with showing things that need to be considered when using this method. But in your case you are already compiling your own version of the SDK, so I think the easier and most straightforward way is to just add that extra code directly in your version of the SDK code. I suspect you don't do that because you want to keep it simple moving to newer versions of the SDK, but you can simply include all the "new" methods of the SDK in a single .prg per library, containing partial classes with the code that extends each class, this will make it very easy to manage everything.
Chris
XIDE Support for migration
Posted: Mon Jul 24, 2017 2:07 pm
by FFF
Chris,
but from what I see in your code, you use those to keep the garbage collector of VO happy be NULLifying yourself several objects before exiting, while normally in .Net this is not needed. But I see you are also closing some DBServers in the Exit functions, would be better to do that also in the X# version of your code, close them manually than wait for them to be auto-closed when the app exits.
Not sure this says what you want to say
I think you recommend to write:
myServer:Close()
but _not_ followed by
myServer := Null_Object
Is this correct? If so, does that mean, that the chain of destruction might fail, if the holding "masterobject" is directly killed, while subobjects still exist?
IMO the whole topic of safely removing complex objects is somewhat fishy, too many urban myths abound
XIDE Support for migration
Posted: Mon Jul 24, 2017 2:09 pm
by wriedmann
Hi Chris,
thank you very much for your comments - I will add them to the document as appropriate. In this forum messages there is so much written down knowledge (and also in email messages) so it would be a real pity to loose it.
Regarding the VO SDK: mine is the Vulcan version, but I don't think I will continue to use this version when you release your runtime - I plan to switch to a version xPorted from the VO version.
Maybe I'll take your recommendation and change the SDK - until now I have tried to remain compatible to the VO version, but since there will be no newer version, it will be worth a tought.
Wolfgang
XIDE Support for migration
Posted: Mon Jul 24, 2017 2:14 pm
by wriedmann
Hi Chris,
and regarding assigning null to my objects after use: I have started this type of coding early in the VO 1.0 days, but I prefer to keep it to help the garbage collector - normally I'm doing that when I don't need an object anymore.
The work of the GC is hard enough, so a bit of help cannot hurt, I think. And after all it is the programmer that knows when an object is not more needed, specially if working with objects referencing each other.
Wolfgang
XIDE Support for migration
Posted: Mon Jul 24, 2017 4:18 pm
by Chris
Hi Karl and Wolfgang,
I know, always when it gets too hot for too long, my messages start to not make a lot of sense
What I meant, is that I saw that in Wolfgang's code that he is manually closing some dbfs in a function that is registered by _RegisterExit(). If this function is not called in the X# version of his app, then the dbfs will not be closed gracefully by his own code, but they will be closed automatically by the runtime when it shut downs, at the moment the app is terminated. While normally there's nothing bad about that, in my opinion it is better to handle dbf closing by own code, same as the VO version of the code does. So my suggestion was to make sure that his "exit" functions get called also in the X# version of his app.
Chris
XIDE Support for migration
Posted: Mon Jul 24, 2017 6:13 pm
by wriedmann
Hi Chris,
ok, I have now modified my code to call AxitGlobal as follows:
Code: Select all
if lInit == false
#ifdef __XSHARP__
AppDomain.CurrentDomain:ProcessExit += AxitGlobalNET
#else
_RegisterExit( @AxitGlobal() )
#endif
lInit: = true
endif
And added a new function:
Code: Select all
function AxitGlobalNET( o as object, e as EventArgs ) as void
FunGlobal( NULL_SYMBOL, nil, #AXIT )
return
This code now compiles in X#, but not more in VO, as VO does not knows about an EventArgs datatype.
Since #ifdef in VO cannot span entity borders, I have added the following definition to my VO-only module VOInt27:
and now my code compiles also in VO.
I'll add this to my PDF document as hint.
Wolfgang
XIDE Support for migration
Posted: Mon Jul 24, 2017 7:44 pm
by Chris
Wolfgang, that looks good to me!
Chris