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.
Related
Status: Sort of solved. Switching Lua.Ref (close equivalent to LuaD LuaObject) to struct as suggested in answer has solved most issues related to freeing references, and I changed back to similar mechanism LuaD uses. More about this in the end.
In one of my project, I am working with Lua interface. I have mainly borrowed the ideas from LuaD. The mechanism in LuaD uses lua_ref & lua_unref to be able to move lua table/function references in D space, but this causes heavy problems because the calls to destructors and their order is not guaranteed. LuaD usually segfaults at least at the program exit.
Because it seems that LuaD is not maintained anymore, I decided to write my own interface for my purposes. My Lua interface class is here: https://github.com/mkoskim/games/blob/master/engine/util/lua.d
Usage examples can be found here:
https://github.com/mkoskim/games/blob/master/demo/luasketch/luademo.d
And in case you need, the Lua script used by the example is here:
https://github.com/mkoskim/games/blob/master/demo/luasketch/data/test.lua
The interface works like this:
Lua.opIndex pushes global table and index key to stack, and return Top object. For example, lua["math"] pushes _G and "math" to stack.
Further accesses go through Top object. Top.opIndex goes deeper in the table hierarchy. Other methods (call, get, set) are "final" methods, which perform an operation with the table and key at the top of the stack, and clean the stack afterwards.
Close everything works fine, except this mechanism has nasty quirk/bug that I have no idea how to solve it. If you don't call any of those "final" methods, Top will leave table and key to the stack:
lua["math"]["abs"].call(-1); // Works. Final method (call) called.
lua["math"]["abs"]; // table ref & key left to stack :(
What I know for sure, is that playing with Top() destructor does not work, as it is not called immediately when object is not referenced anymore.
NOTE: If there is some sort of operator to be called when object is accessed as rvalue, I could replace call(), set() and get() methods with operator overloads.
Questions:
Is there any way to prevent users to write such expressions (getting Top object without calling any of "final" methods)? I really don't want users to write e.g. luafunc = lua["math"]["abs"] and then later try to call it, because it won't work at all. Not without starting to play with lua_ref & lua_unref and start fighting with same issues that LuaD has.
Is there any kind of opAccess operator overloading, that is, overloading what happens when object is used as rvalue? That is, expression "a = b" -> "a.opAssign(b.opAccess)"? opCast does not work, it is called only with explicit casts.
Any other suggestions? I internally feel that I am looking solution from wrong direction. I feel that the problem reside in the realm of metaprogramming: I am trying to "scope" things at expression level, which I feel is not that suitable for classes and objects.
So far, I have tried to preserve the LuaD look'n'feel at interface user's side, but I think that if I could change the interface to something like following, I could get it working:
lua.call(["math", "abs"], 1); // call lua.math.abs(2)
lua.get(["table", "x", "y", "z"], 2); // lua table.x.y.z = 2
...
Syntactically that would ensure that reference to lua object fetched by indexing is finally used for something in the expression, and the stack would be cleaned.
UPDATE: Like said, changing Lua.Ref to struct solved problems related to dereferencing, and I am again using reference mechanism similar to LuaD. I personally feel that this mechanism suits the LuaD-style syntax I am using, too, and it can be quite a challenge to make the syntax working correctly with other mechanisms. I am still open to hear if someone has ideas to make it work.
The system I sketched to replace references (to tackle the problem with objects holding references living longer than lua sandbox) would probably need different kind of interface, something similar I sketched above.
You also have an issue when people do
auto math_abs = lua["math"]["abs"];
math_abs.call(1);
math_abs.call(3);
This will double pop.
Make Top a struct that holds the stack index of what they are referencing. That way you can use its known scoping and destruction behavior to your advantage. Make sure you handle this(this) correctly as well.
Only pop in the destructor when the value is the actual top value. You can use a bitset in LuaInterface to track which stack positions are in use and put the values in it using lua_replace if you are worried about excessive stack use.
In a Delphi 7 project we installed FastMM. Soon after that we noticed one of the forms started to issue Abstract Error message on close. I have debugged this extensively and I can't find the reason so far. The usual reason for this error message doesn't seem to apply here. The application doesn't define abstract classes. I also searched the form for a possible use of TStrings or something like that. Most importantly, we didn't (well, we think we didn't) make any changes to this form. It just broke.
Are there some other possible causes for this error besides trying to call unimplemented method?
Is there some possibilty that FastMM has enabled some obscure bug in the application, that remained hidden until now?
If the answer to these questions is no, then I'll just continue to search for an unimplemented method call, relieved that I am not missing something else.
If there is memory corruption then all sort of errors can be raised and it is very difficult to find the cause.
To answer your questions: 1) Yes abstract error can also be caused by memory corruption, and 2) Yes enabling FastMM can make bugs visible that normally pass unnoticed (but should still be fixed).
Some general advice for finding memory errors:
Try "FullDebugMode" setting in FastMM.
Make sure everything you Create is matched with a Free.
Make sure nothing is freed more than once.
Make sure an object is not used after it has been freed (or before it has been created).
Turn on hints and warnings (and fix them when they occur).
"It just broke" - it was probably always broke but now you know.
I have seen problems when closing a form as part of a button event. The form gets destroyed and then the remainder of the button messages get dispatched to a no-longer existing button. The Release method avoids this by (from memory) posting a wm_close message back to the form
Answer to question 1 "Are there some other possible causes for this error besides trying to call unimplemented method?"
Yes. This is what caused in my case an Abstract Error:
TWinControl(Sender).Visible:= FALSE;
This worked when sender was a TButton but raised the error (of course) when the sender was something else (like TAction). It was obviously my fault. I should have used "as" instead of a hard typecast.
Answer to question 2: Yes. I have seen that happening too. We should be very clear that this doesn't mean that FastMM is buggy. The bug was 'dormant'. FastMM only triggered it.
Actually you should rely on FastMM even more to find your issue. Switch FastMM to full debug mode for this. It will help you with:
Make sure an object is not used after it has been freed (or before it
has been created)
Also, in a few cases, the whole project was screwed up and I got the Abstract error. Nothing worked until I deleted the DPROJ file. Just do a compare between your current DPROJ file and the one in your back and you will see how the IDE f**** up the file.
You MUST also fix ALL warnings the compiler shows! The compiler is serious about that. It wouldn't raise an warning without a valid reason. Fix that and you will probably fix your problem.
In this particular case I would also replace all .Free with FreeAndNil().
You could try to add u_dzAbstractHandler to your project. It should raise the abstract error where the method was called, so it is easier to debug it. Of course this only helps when the error occurs when running in the debugger.
https://osdn.net/projects/dzlib-tools/scm/svn/blobs/head/dzlib/trunk/src/u_dzAbstractHandler.pas
Could be that one of your abstract functions/procedures in the base class is not implemented;
try this :
e.g
type
TBaseClass = class (TObject)
public
procedure DoSomething; virtual; abstract; //not implemented procedure
end;
type
TInheritedClass = class (TBaseClass)
public
procedure DoSomething; override;
end;
//Implementation
procedure TInheritedClass.DoSomething;
begin
//your code
end;
I have been reading up on the c++ auto_ptr and unique_ptr and stuff and thought to try and use them in a class I am playing with... but I was having trouble getting it to work...
How would I convert these pointers to auto pointers or some equivalent so the deletion of the pointers is handled automatically?
Header - http://ideone.com/Z9bc5
Body - http://ideone.com/WfwBY
At the moment it is working using normal pointers but I sometimes get a access violation error. I am pretty sure I know what it causing it.. but the "best" way might be to use the automatic deletion stuff recently added to c++11?
Thanks in advance.
Don't use auto_ptr. Try one of unique_ptr or shared_ptr. Here's Sutter explaining when to use which:
When in doubt, prefer unique_ptr by default, and you can always later move-convert to shared_ptr if you need it. If you know from the start you need shared ownership, however, go directly to shared_ptr via make_shared (see #2 below).
Also from his blog-post:
3. What’s the deal with auto_ptr?
auto_ptr is most charitably characterized as a valiant attempt to
create a unique_ptr before C++ had move semantics.
auto_ptr is now deprecated, and should not be used in new code. When
you get a chance, try doing a global search-and-replace of auto_ptr to
unique_ptr in your code base; the vast majority of uses will work the
same, and it might expose (as a compile-time error) or fix (silently)
a bug or two you didn’t know you had.
So, your member declarations change from:
sf::Texture * tSpriteSheet;
to:
std::unique_ptr<sf::Texture> tSpriteSheet;
As for member functions which return a raw pointer you have but the obvious choice: You cannot return a unique_ptr if the class is not movable. So, you can either:
Keep the signature as-is
Return a const& unique_ptr<T>
Return a reference to the object
Choose the one that suits your needs the best.
What are the pros and cons in using fluent interfaces in Delphi?
Fluent interfaces are supposed to increase the readability, but I'm a bit skeptical to have one long LOC that contains a lot of chained methods.
Are there any compiler issues?
Are there any debugging issues?
Are there any runtime/error handling issues?
Fluent interfaces are used in e.g. TStringBuilder, THTMLWriter and TGpFluentXMLBuilder.
Updated:
David Heffernan asked which issues I was concerned about. I've been given this some thought, and the overall issue is the difference between "explicitly specifying how it's done" versus "letting the compiler decide how it's done".
AFAICS, there is no documentation on how chained methods actually is handled by the compiler, nor any specification on how the compiler should treat chained methods.
In this article we can read about how the compiler adds two additional var-parameters to methods declared as functions, and that the standard calling convention puts three params in the register and the next ones on the stack. A "fluent function method" with 2 params will therefor use the stack, whereas an "ordinary procedure method" with 2 params only uses the register.
We also know that the compiler does some magic to optimize the binary (e.g. string as function result, evaluation order, ref to local proc), but sometimes with surprising side effects for the programmer.
So the fact that the memory/stack/register-management is more complex and the fact that compiler could do some magic with unintentional side effects, is pretty smelly to me. Hence the question.
After I've read the answers (very good ones), my concern is strongly reduced but my preference is still the same :)
Everybody is just writing about negative issues so let's stress some positive issues. Errr, the only positive issue - less (in some cases much less) typing.
I wrote GpFluentXMLBuilder just because I hate typing tons of code while creating XML documents. Nothing more and nothing less.
The good point with fluent interfaces is that you don't have to use them in the fluent manner if you hate the idiom. They are completely usable in a traditional way.
EDIT: A point for the "shortness and readability" view.
I was debugging some old code and stumbled across this:
fdsUnreportedMessages.Add(CreateFluentXml
.UTF8
.AddChild('LogEntry')
.AddChild('Time', Now)
.AddSibling('Severity', msg.MsgID)
.AddSibling('Message', msg.MsgData.AsString)
.AsString);
I knew immediately what the code does. If, however, the code would look like this (and I'm not claiming that this even compiles, I just threw it together for demo):
var
xmlData: IXMLNode;
xmlDoc : IXMLDocument;
xmlKey : IXMLNode;
xmlRoot: IXMLNode;
xmlDoc := CreateXMLDoc;
xmlDoc.AppendChild(xmlDoc.CreateProcessingInstruction('xml',
'version="1.0" encoding="UTF-8"'));
xmlRoot := xmlDoc.CreateElement('LogEntry');
xmlDoc.AppendChild(xmlRoot);
xmlKey := xmlDoc.CreateElement('Time');
xmlDoc.AppendChild(xmlKey);
xmlData := xmlDoc.CreateTextNode(FormatDateTime(
'yyyy-mm-dd"T"hh":"mm":"ss.zzz', Now));
xmlKey.AppendChild(xmlData);
xmlKey := xmlDoc.CreateElement('Severity');
xmlDoc.AppendChild(xmlKey);
xmlData := xmlDoc.CreateTextNode(IntToStr(msg.MsgID));
xmlKey.AppendChild(xmlData);
xmlKey := xmlDoc.CreateElement('Message');
xmlDoc.AppendChild(xmlKey);
xmlData := xmlDoc.CreateTextNode(msg.MsgData.AsString);
xmlKey.AppendChild(xmlData);
fdsUnreportedMessages.Add(xmlKey.XML);
I would need quite some time (and a cup of coffee) to understand what it does.
EDIT2:
Eric Grange made a perfectly valid point in comments. In reality, one would use some XML wrapper and not DOM directly. For example, using OmniXMLUtils from the OmniXML package, the code would look like that:
var
xmlDoc: IXMLDocument;
xmlLog: IXMLNode;
xmlDoc := CreateXMLDoc;
xmlDoc.AppendChild(xmlDoc.CreateProcessingInstruction(
'xml', 'version="1.0" encoding="UTF-8"'));
xmlLog := EnsureNode(xmlDoc, 'LogEntry');
SetNodeTextDateTime(xmlLog, 'Time', Now);
SetNodeTextInt(xmlLog, 'Severity', msg.MsgID);
SetNodeText(xmlLog, 'Message', msg.MsgData.AsString);
fdsUnreportedMessages.Add(XMLSaveToString(xmlDoc));
Still, I prefer the fluent version. [And I never ever use code formatters.]
Compiler issues:
If you're using interfaces (rather than objects), each call in the chain will result in a reference count overhead, even if the exact same interface is returned all the time, the compiler has no way of knowing it. You'll thus generate a larger code, with a more complex stack.
Debugging issues:
The call chain being seen as a single instruction, you can't step or breakpoint on the intermediate steps. You also can't evaluate state at intermediate steps.
The only way to debug intermediate steps is to trace in the asm view.
The call stack in the debugger will also not be clear, if the same methods happens multiple times in the fluent chain.
Runtime issues:
When using interfaces for the chain (rather than objects), you have to pay for the reference counting overhead, as well as a more complex exception frame.
You can't have try..finally constructs in a chain, so no guarantee of closing what was opened in a fluent chain f.i.
Debug/Error logging issues:
Exceptions and their stack trace will see the chain as a single instruction, so if you crashed in .DoSomething, and the call chain has several .DoSomething calls, you won't know which caused the issue.
Code Formatting issues:
AFAICT none of the existing code formatters will properly layout a fluent call chain, so it's only manual formatting that can keep a fluent call chain readable. If an automated formatter is run, it'll typically turn a chain into a readability mess.
Are there any compiler issues?
No.
Are there any debugging issues?
Yes. Since all the chained method calls are seen as one expression, even if you write them on multiple lines as in the Wikipedia example you linked, it's a problem when debugging because you can't single-step through them.
Are there any runtime/error handling issues?
Edited: Here's a test console application I wrote to test the actual Runtime overhead of using Fluent Interfaces. I assigned 6 properties for each iteration (actually the same 2 values 3 times each). The conclusions are:
With interfaces: 70% increase in runtime, depends on the number of properties set. Setting only two properties the overhead was smaller.
With objects: Using fluent interfaces was faster
Didn't test records. It can't work well with records!
I personally don't mind those "fluent interfaces". Never heard of the name before, but I've been using them, especially in code that populates a list from code. (Somewhat like the XML example you posted). I don't think they're difficult to read, especially if one's familiar with this kind of coding AND the method names are meaningful. As for the one long line of code, look at the Wikipedia example: You don't need to put it all on one line of code.
I clearly remember using them with Turbo Pascal to initialize Screens, which is probably why I don't mind them and also use them at times. Unfortunately Google fails me, I can't find any code sample for the old TP code.
I would question the benefit of using "fluent interfaces".
From what I see, the point is to allow you to avoid having to declare a variable. So the same benefit the dreaded With statement brings, with a different set of problems (see other answers)
Honestly I never understood the motivation to use the With statement, and I don't understand the motivation to use fluent interfaces either. I mean is it that hard to define a variable ?
All this mumbo jumbo just to allow laziness.
I would argue that rather than increase readability it, which at first glance it seems to do by having to type/read less, it actually obfuscates it.
So again, I ask why would you want to use fluent interfaces in the first place ?
It was coined by Martin Fowler so it must be cool ? Nah I ain't buying it.
This is a kind of write-once-read-never notation that is not easy to understand without going through documentation for all involved methods. Also such notation is not compatible with Delphi and C# properties - if you need to set properties, you need to rollback to using
common notations as you can't chain property assignments.
I am looking for hints on how to debugging a crash in an application that uses the MS XML wrappers in the Delphi VCL. I suspect memory corruption, or some kind of obscure evil thing happening between objects and interfaces, such as reference counting bugs, or heap corruption. The question is, in effect: how do I debug such a crash?
This particular code makes heavy internal use of and extends on the base XmlIntf Interfaces (IXMLNode). ISomethingCustom is an interface that extends IXMLNode. THe problem happens where we crash somewhere in a recursive function that is passed an ISomethingCustom which is also (or supports also, in interface terms) IXMLNode.
boolean UtilityFunction( aNode: ISomethingCustom ):Boolean;
begin
if not Assigned(aNode) then exit; // this works. great.
if not Assigned(aNode.ParentNode) then exit; // this DOES NOT WORK.
// code that blows up if aNode.ParentNode is not assigned.
end;
The situation is that the aNode is also IXMLNode, and IXMLNode.ParentNode value is assigned (not nil), and yet it points to a COM object that may have been freed, destroyed, or corrupted somehow. I am trying to figure out WHAT is going on when an interface pointer can appear to be valid, but the object behind it has been nuked somehow.
Checking Assigned(aNode.ParentNode) returns TRUE, even when, if you were to attempt a cast in the debugger (at runtime only, not in the code), like this:
inspect/evaluate aNode
inspect/evaluate TInterfacedObject(aNode).ClassName
(works in Delphi 2010, at least!)
now cast TWhateverClassNameYouGotBefore(aNode).
In the debugger I now see that this is NIL. WHich may mean that
the magic "casting interface back to
the object" feature that is new in
delphi 2010, is failing.
I believe I am trying to debug a problem where heaps are corrupted, or COM objects are corrupt on the heap, because of a reference counting problem.
I really think that nobody should ever have the situation arise where an interface appears valid, but the object underneath has been deleted. I really would like to know what to do, and what is going on.
Although you haven't shown it in your code, your comments seem to indicate that you're type-casting the interface variable to a class type. That's not allowed. I've described why:
Why can’t I cast an interface reference to an object reference?
Interface references and object references don't point to the same things. Therefore, calling a method on one when the compiler thinks you have the other will yield unexpected results. You were unlucky because the code continued to run instead of crashing with an access violation, which would have been a bigger indication that you were doing something wrong.
My article above concludes by suggesting you use the JclSysUtils.GetImplementorOfInterface function from the JCL if you have a Delphi-implemented interface and the interface offers no function of its own for revealling the underlying object.
Wild guess: Have you tried to put aNode.ParentNode in a local variable and use it in the rest of the Utilityfunction:
function UtilityFunction(aNode: ISomethingCustom): Boolean;
var
lParentNode: INode;
begin
if not Assigned(aNode) then exit; // this works. great.
lParentNode := aNode.ParentNode;
if not Assigned(lParentNode) then exit;
// code that uses lParentNode.
end;
My suggestion is to make sure that the ParentNode function is actually called in Assigned(aNode.ParentNode). There are some nasty corner-cases in Delphi where a procedure/function without arguments doesn't get called, but rather it's reference is taken when you omit the parenthesis's.
Try to change it to Assigned(Anode.ParentNode()) (which should have the same effect as François suggestion).