Is it ok to create an object before Application.Initialize? - delphi

Is it ok to create an object (my own class) before Application.Initialize?

Is it ok to create an object (my own class) before Application.Initialize?
Certainly. You can do anything you like in your program (*.dpr file).
In fact, you may have been doing this already, without knowing it. If you have ever used the initialization section of a unit -- or a modern class constructor -- you have executed your own code prior to Application.Initialize.
Writing custom code at this early time of your program's lifetime is neither unusual nor bad practice.
But you should be extra careful, of course, because the pre-Application.Run environment is subtly different from the Application.Run environment. For instance, an unhandled exception will kill your app.

Related

Best practice for resolving in Spring4D?

In the spring4d demos, ServiceLocator.GetService<MyType>('Name') is used to resolve the types. But why not use GlobalContainer.Resolve<MyType>('Name')? I don't see any advantage in this approach...
There is one use case, where I use ServiceLocator:
when coding to make legacy code projects unit-testable...
There is an old project, where in mulitiple places, there are constructor calls of an object, which I write tests for (new and changed methods only, in classes, where injection is not possible, e.g. when a Form is created and destroyed in a button event).
In unit-tests, spring4d is helpful to instantiate the class-under-test:
I can use the GlobalContainer in the dpr for the production project and a special (test-only) TContainer-object which is constructed in Testfixture.Setup and destroyed in Testfixture.TearDown... I also re-initialize the global Service-Locator to use my Test-Container (Reason: I have bad experiences to use GlobalContainer in Test, you cannot un-register a type from GlobalContainer in Testfixture.TearDown).
So now, I got a big method in the dpr, where I register all types to GlobalContainer in the production-code project. In the Setup-Method of my test-fixture-class, I register all types needed for the test to my Testing-Container. And in the Methods, that I changed to make them unit-testable, I construct the classes-under-test with ServiceLocator, where formerly constructor-calls where used.
For me, it is the only way to make such a legacy-code project unit-testable... But my strategic goal is to replace most of this code (part-by-part, including the re-initialized ServiceLocators) one day. It is just not possible to replace it now (too much costs, too much risk...).

Delphi - Why is TObject.InitInstance public?

I'm somewhat new to Delphi, and this question is just me being curious. (I also just tried using it by accident only to discover I'm not supposed to.)
If you look at the documentation for TObject.InitInstance it tells you not to use it unless you're overriding NewInstance. The method is also public. Why not make it protected if the user is never supposed to call it?
Since I was around when this whole Delphi thing got started back around mid-1992, there are likely several answers to this question. If you look at the original declaration for TObject in Delphi 1, there weren't any protected/private members on TObject. That was because very early on in the development of Delphi and in concert with the introduction of exceptions to the language, exceptions were allocated from a different heap than other objects. This was the genesis of the NewInstance/InitInstance/CleanupInstance/FreeInstance functions. Overriding these functions on your class types you can literally control where an object is allocated.
In recent years I've used this functionality to create a cache of object instances that are literally "recycled". By intercepting NewInstance and FreeInstance, I created a system where instances are not returned to the heap upon de-allocation, rather they are placed on a lock-free/low-lock linked list. This makes allocating/freeing instances of a particular type much faster and eliminates a lot of excursions into the memory manager.
By having InitInstance public (the opposite of which is CleanupInstance), this would allow those methods to be called from other utility functions. In the above case I mentioned, InitInstance could be called on an existing block of memory without having to be called only from NewInstance. Suppose NewInstance calls a general purpose function that manages the aforementioned cache. The "scope" of the class instance is lost so the only way to call InitInstance is of it were public.
One of these days, we'll likely ship the code that does what I described above... for now it's part of an internal "research" project.
Oh, as an aside and also a bit of a history lesson... Prior to the Delphi 1 release, the design of how Exception instances were allocated/freed was returned to using the same heap as all the other objects. Because of an overall collective misstep it was assumed that we needed to allocate all Exception object instances to "protect" the Out of memory case. We reasoned that if we try and raise an exception because the memory manager was "out of memory", how in the blazes would we allocate the exception instance!? We already know there is no memory at that point! So we decided that a separate heap was necessary for all exceptions... until either Chuck Jazdzewski or Anders Heijlsberg (I forget exactly which one), figured out a simple, rather clever solution... Just pre-allocate the out of memory exception on startup! We still needed to control whether or not the exception should ever actually be freed (Exception instances are automatically freed once handled), so the whole NewInstance/FreeInstance mechanism remained.
Well never say never. In the VCL too much stuff is private and not virtual as it is, so I kinda like the fact that this stuff is public.
It isn't really necessary for normal use, but in specific cases, you might use it to allocate objects in bulk. NewInstance reserves a bit of memory for the object and then calls InitInstance to initialize it. You could write a piece of code that allocates memory for a great number of objects in one go, and then calls InitInstance for different parts of that large block to initialize different blocks in it. Such an implementation could be the base for a flyweight pattern implementation.
Normally you wouln't need such a thing at all, but it's nice that you can if you really want/need to.
How it works?
The fun thing is: a constructor in Delphi is just some method. The Create method itself doesn't do anything special. If you look at it, it is just a method as any other. It's even empty in TObject!
You can even call it on an instance (call MyObject.Create instead of TMyObject.Create), and it won't return a new object at all. The key is in the constructor keyword. That tells the compiler, that before executing the TAnyClass.Create method, it should also construct an actual object instance.
That construction means basically calling NewInstance. NewInstance allocates a piece of memory for the data of the object. After that, it calls InitInstance to do some special initialization of that memory, starting with clearing it (filling with zeroes).
Allocating memory is a relatively expensive task. A memory manager (compiled into your application) needs to find a free piece of memory and assign it to your object. If it doesn't have enough memory available, it needs to make a request to Windows to give it some more. If you have thousands or even millions of objects to create, then this can be inefficient.
In those rare cases, you could decide to allocate the memory for all those objects in one go. In that case you won't call the constructor at all, because you don't want to call NewInstance (because it would allocate extra memory). Instead, you can call InitInstance yourself to initialize pieces of your big chunk of memory.
Anyway, this is just a hypotheses of the reason. Maybe there isn't a reason at all. I've seen so many irrationally applied visibility levels in the VCL. Maybe they just didn't think about it at all. ;)
It gives developers a way to create object not using NewInstance (memory from stack/memory pool)

I found the ComClass, now how do I reference it?

I've written a small COM Server in Delphi 2010 that acts as a plug-in into a retail application. The retail application looks for a "discover" interface which registers any number of additional interfaces calling TAutoObjectFactory.Create for each one. This is working just fine--all the plug-in interfaces function as designed.
But now I'd like to call a public method of one interface from another interface so I don't have to duplicate code. Seems simple enough, just call ComClassManager.ForEachFactory looking for the ClassID of the interface I need to use. Got that working, too!
But now that I found the class, I'm stumped by a seemingly trivial final step: how to use or cast the class (or class reference?) I've located to actually call one of its methods.
In the "FactoryProc" I've sent to ForEachFactory, I assume the ComClass property of TComObjectFactory is what I'm after, but it's of type TClass, a class reference to the actual class object to which it points (at least I hope I'm understanding this correctly). I'm a little fuzzy on class references and my attempts to cast or otherwise de-reference this property has resulted in access violations or compiler errors.
Any suggestions?
You're right in your comment, ComClassManager deals with classes, not instances. What you need is (your application-local implementation of) running object table (or something similar), so plugin instances can interact with each other.
How to actually implement it depends on what you really need, e.g. call methods on all running instances, or only on instances of specific classes.

What percent of functions on OS X are called by the Objective-C runtime?

I'd like to get a firmer grasp of how frequently the runtime in any language that requires one is being called. In this case, I'm specifically interested in knowing:
Of all the function calls getting executed on an OS X or iOS system in any given second (approximations are of course necessary) how many of those are Objective-C runtime functions (i.e. functions that are defined by the runtime)?
Of course it depends on your application, but in general the answer is "a whole lot". Like, a whole freaking lot.
If you really want to see numbers, I'd recommend using dtrace to log all runtime functions as they're called. This blog entry talks about how to do such a thing.
A lot. Here are just a few examples.
Every time you send a message, the actual message sending is done by a runtime function (this is in fact the most called runtime function in pretty much any objective C program).
NSObject class and protocol are not part of the standard library but part of the runtime, therefore any method that ends up executing to the default NSObject implementation is in fact executing runtime code.
Every time you execute a default property accessor (either read or write), that's part of the runtime.
If you use ARC, every time you access a weak reference (either for reading or writing it) that's a runtime function.
Objc runtime includes the C runtime, so anything that involves a C runtime function (for example passing a large structure by value or returning it) is in fact calling into the runtime.
and more.

Delphi Win32 Programming/Access Violation problems

I wasn't entirely sure how to name this, so apologies in advance.
You see, I'm trying to teach myself Win32/DirectX programming, utilizing Delphi (my language of choice) using this site - http://rastertek.com/tutindex.html
Of course, the site being all in C++, I have to port it to Delphi. It seemed simple enough, at first. I'm on the second tutorial for DirectX 11 - setting up the framework and getting the initial window to show up.
Now for my actual problem. I was getting Access Violation errors. So I found and started to use MadExcept to try and find out what was going on. So it tells me the lines, but I'm clueless as to how to solve the issues at hand.
I have everything set up to mimic as well as I can the original source code. The only real difference being that in the instances where a pointer to a class for a variable, such as the case with m_input, m_grahics, and system, I made a type for those. So I have the TSystemClass, TInputClass, TGraphicsClass, and then I have PSystemClass, etc. that = ^TSystemClass, etc. I figured that this would make things a bit simpler and more neater. On a side note, I assume it should be said, but I for the construction of the copy constructors made the initial classes inherit from TPersistent so I could use it's Assign procedure.
So, back to the Access Violation errors. So first, the problem was in the main program with system being of type PSystemClass. So for a reason unknown to me, when I tried to use system.create, it was at that very instant, creating the access violation. I then realized however that I wasn't assigning system the system.create. So I tried this, and it said that, and rightfully so I suppose, at compile time an error that the two were incompatible since system.create is of type TSystemClass, and system is of PSystemClass. So I tried typecasting it, and that worked. but once again, still getting the dreaded access violations.
So then I had an odd idea, maybe I should call the regular constructor right from the TSystemClass itself. And I tried, needed to typecast again. So I did. And it worked! No longer an access violation error there! Now... New problem! Or rather in this case "problems". There's 3 things now listed in the call stack in MadExcept. The first one:
m_hinstance := GetModuleHandle(nil);
It's saying that this is causing an access violation error. Though why is this, exactly? From what I understand and have read, if GetModuleHandle is set to null/nil, it should retrieve the handle for the file that called it, right? And from what the documentation says, that should be executable.
However note: I'm not sure if the fact that I have the main program, the systemclass stuff, the inputclass stuff, and the graphicsclass stuff, all in different program/unit files to mimic the nature of the original source code. So is this possibly what's causing it? And if so how would I fix it? By putting all of the code from the unit files into the main program file? Though that, in my own personal opinion, would be quite messy and unintuitive.
The next one baffles me even more.
InitializeWindows(ScreenWidth, ScreenHeight);
I'm not dealing with anything other then a function to register the window class and set things up for the window and all here. So I'm not quite sure what the problem here is since it only deals with 2 parameters and they're defined and all already before it's called. So I'm not quite sure what the problem here is at all and what exactly is causing the access violation.
and then finally the final one is in the main program:
return := system.initialize;
Return is what I used in all instances of the result variable of the original source code, as result is of course a built in variable of all functions.
I suppose if system is never able to properly do what it's meant to do then something could/should happen here. Likewise, because I used TSystemClass.Create (typecasted to PSystemClass) earlier to create system would that do anything here? And is it possibly linked to the other two because they're not able to do their own thing properly?
And on a final note; there is one last thing actually on the call stack in MadExcept.
It says Kernel32.dll in the module section, but aside from the main thread, it lists nothing else. (If this information is needed I'll gladly put it up).
Thanks in advance to anyone who's read this far and I hope to find some help on this problem so I may further my studies.
You're instantiating your classes all wrong. Here's an example from TSystemClass.Initialize:
m_Input := PInputClass(m_Input.create);
That's a variable you declared as a PInputClass.
Earlier, in TSystemClass.Create, you initialized that variable:
m_Input := nil;
So, since you have a null reference, it should be clear that you can't call any methods on it. In particular, you cannot call Create on it. Instead, call Create on the class you want to instantiate: TInputClass.Create.
That constructor returns a value of the type you constructed, a TInputClass. It doesn't return a PInputClass, so your type-cast is wrong. As Cosmin's comment explains, Delphi object variables are already pointers. It's exceedingly rare to have to declare a pointer type based on Delphi classes. The correct code is this:
m_Input := TInputClass.Create;
After that line, you check whether m_Input is null. You never have to do that in Delphi; a constructor either returns a valid object, or it doesn't return at all. If there's a problem constructing an object, the constructor throws an exception and the assignment statement never executes. (The original C++ code does it wrong, too. The new operator hasn't returned a null pointer on failure for over a decade, long before anyone was in a position to start writing a DirectX 11 tutorial.)
You should first of all try to get rid of the TPersistent inheritance. If you want to pass an object to a library its interface should be exactly the same as the original that is used in C++. By inheriting from TPersistent you take a whole lot of load into your class that might be not needed or might even be the reason of your problems.
Additionally it would help if you posted the exact output of the exceptions. Or even the CallStack. That might help tracing down the error.

Resources