-
Content Count
3586 -
Joined
-
Last visited
-
Days Won
176
Everything posted by David Heffernan
-
I called it like this: procedure TPythonEngine.Execute(const Code: PAnsiChar; const globals, locals: IPyDictionary); var retval: PPyObjectRef; begin retval := PyRun_StringFlags(Code, Py_file_input, globals.Ref, locals.Ref, nil); CheckError(Assigned(retval)); DecRef(retval); end; I passed exit() in via the Code argument, and empty dicts in globals and locals. retval comes back nil and CheckError is my function to extract tracebacks. I know we looked at way back when we first embedded Python. I honestly don't recall the details. I think some part of the decision will be my own fastidiousness to have total control over everything, and as you know P4D has a huge range of functionality. We only scratch at the surface of what P4D can do. Our usage is a finite element structural engineering code which allows users to customise some parts of the calculation and post-processing by calling Python code that they provide. So we just need to create instances, populate attributes, and call the user function passing in those instances. Then we need to read out the attributes from those instances after the user script has run. It's such a tiny part of what P4D offers, that we just did it ourself. The way our wrapper exposes Python is much closer to the metal than P4D I believe. We use interfaces to wrap Python objects, and because they are also reference counter, that fits really nicely with the Python ref count. When our implementing wrapper objects are destroyed (because the Delphi ref count goes to zero), we just call Py_DecRef on the underlying Python object. I seem to recall that in P4D client code you sometimes have to deal with the Python ref code, but we've been able to hide that from our client code. Anyway, embedded Python is a truly remarkable achievement, and P4D is clearly a fantastic library. Our software would be far poorer without embedded Python.
-
You have not defined a type there. You've defined an alias. That's a crucial distinction that is very relevant for the behaviour you observe. I don't really understand what your alias is buying you. I'd prefer to be explicit here.
-
If you read @pyscripter's comment you will realise that what you need is impossible. Usually in the face of impossibility it's time to look for other approaches. I was able to catch SystemExit when I ran a single line of code using PyRun_StringFlags but I guess you are executing a module and I suppose that is treated differently. Anyway, it's time to recalibrate expectations.
-
It's better to fix the original code. Either by using ReadBuffer, or by comparing Read return value against the number of bytes requested. Is this really Embarcadero code? Hard to believe they'd write Readed!
-
Use websearch. That's all we would do.
-
This code can fall into an in infinite loop if Stream.Read fails
-
Yes, but it easier just to use a command line tool to do this. You don't need any components. Delphi comes with a library of hash functions. That doesn't make much sense. A hash function is a function that maps an arbitrary length array of bytes to a fixed length array of bytes. Your image file is the input to the hash function. Multiple different inputs can yield the same has for fairly obvious reasons. Reading about hash functions would be useful for you.
-
TNothingable<T>
David Heffernan replied to Attila Kovacs's topic in Algorithms, Data Structures and Class Design
You mean a nullable type? There are lots of implementations. Spring has one but there are plenty more. -
We are going round in circles. I wouldn't call exit if I wanted the process not to be terminated. I can't for the life of me imagine why you want to call exit otherwise. That said, in my own wrapper of embedded Python, if I call PyRun_StringFlags passing exit() then it doesn't terminate the process, and the call returns an error with a traceback. So maybe python4delphi is doing something else. Whilst I'm familiar with calling embedded Python from Delphi, I use my own wrapper. You probably need specific python4delphi knowledge, but you asked the question in the VCL sub-forum by mistake. Perhaps you need to ask a mod to migrate it?
-
I wouldn't have thought so. You asked for the process to be terminated. I'm pretty sure that you have selected the wrong solution to your problem, and are trying to find a way to make it work. You should step back and find the right solution.
-
Micro optimization: Split strings
David Heffernan replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
That's just a bug -
This looks like it should be in the python4delphi area of the site. If you don't want exit to terminate the process then don't call exit(). It's really that simple. For sure you could catch that exception which IIRC is SystemExit. But that doesn't make sense to me. If you don't want to exit, don't exit.
-
spinlock primitives
David Heffernan replied to dummzeuch's topic in Algorithms, Data Structures and Class Design
It could but I don't have one and I'd have to add one, which i guess is why I put it there. -
spinlock primitives
David Heffernan replied to dummzeuch's topic in Algorithms, Data Structures and Class Design
FWIW this is my spin lock TSpinLock = class private FLock: Integer; public procedure Acquire; procedure Release; end; procedure TSpinLock.Acquire; begin Assert(AlignedOn32bitBoundary(@FLock)); while AtomicCmpExchange(FLock, 1, 0)<>0 do begin //signal to CPU that we are spinning; see, for example, http://msdn.microsoft.com/en-us/magazine/cc163726.aspx YieldProcessor; end; end; procedure TSpinLock.Release; begin AtomicExchange(FLock, 0); end; It's only useful on x86/x64 because Emba haven't provided an implementation of YieldProcessor for other processors! I suspect that professional spin locks use different yield methods depending on how long they have been spinning. -
Max string literal length = 255
David Heffernan replied to Lars Fosdal's topic in RTL and Delphi Object Pascal
In reality you want to split them over multiple lines once they are that long so it's rare that it affects you. -
spinlock primitives
David Heffernan replied to dummzeuch's topic in Algorithms, Data Structures and Class Design
Aren't you meant to use the YIELD instruction (if I've remembered it's name right) -
Delphi service in a domain controlled environment
David Heffernan replied to thomh's topic in Network, Cloud and Web
What happens in a do nothing Delphi service? Do they stop too? If not then the problem is likely in your service code. -
class operator, AND/OR/XOR question
David Heffernan replied to A.M. Hoornweg's topic in RTL and Delphi Object Pascal
It's explained in the documentation. Which should always be the first port of call when contemplating such an issue. Its here: http://docwiki.embarcadero.com/RADStudio/en/Operator_Overloading_(Delphi) I could highlight the key text for you, but I'm sure you are more than capable of finding it. -
How do you identify bottleneck in Delphi code?
David Heffernan replied to Mike Torrettinni's topic in Tips / Blogs / Tutorials / Videos
Your conclusion in that topic is wrong. You can make huge algorithmic gains but you choose not to. I've no idea why not. -
Quickly zero all local variables?
David Heffernan replied to A.M. Hoornweg's topic in RTL and Delphi Object Pascal
It's passed by value in your procedure. The caller can't see the change. Also, the original concept would be something that would zeroise local vars without them needing to be listed. Your code fails in every possible way to meet the requirements. And indeed any user defined function would fail, because the asker wants to have the compiler do it. -
Quickly zero all local variables?
David Heffernan replied to A.M. Hoornweg's topic in RTL and Delphi Object Pascal
Why would anybody use code that does nothing? You call a procedure passing parameters by value. Then that procedure modifies those parameters. You've basically done this: procedure Foo(Value: Integer); begin Value := 0; end; I don't think it takes a genius to see that this is pointless. Furthermore, were your function able to do what you think it can, it's still useless. Who the heck is going to call a procedure passing a list of variables, to have that procedure set them to zero? You'll just set them to zero at the call site using the assignment operator. You really think people are going to write: prcInitItPlease([lMyVarLocalThiProc, lMyOtherVarLocal]); (which does not and cannot work as noted above) rather than lMyVarLocalThiProc := 0; lMyOtherVarLocal := 0; Honestly, this thread is mind boggling! -
Quickly zero all local variables?
David Heffernan replied to A.M. Hoornweg's topic in RTL and Delphi Object Pascal
This just modifies local copies of the args, not before burning a ton of cycles boxing them in variants. -
How do you identify bottleneck in Delphi code?
David Heffernan replied to Mike Torrettinni's topic in Tips / Blogs / Tutorials / Videos
This is for sure worth doing. But is that what you mean when you talk about a 10% improvement above? Or are you measuring 10% in just a single function? And sorry to hark back to it, but in your StringReplace topic recently you were concentrating on utterly the wrong thing. There was a massive opportunity to optimise that code, and you have chosen not to take it. For reasons that escape me. -
How do you identify bottleneck in Delphi code?
David Heffernan replied to Mike Torrettinni's topic in Tips / Blogs / Tutorials / Videos
@Mike Torrettinni when you talk about a 10% improvement, do you mean in the execution time for one function, or do you mean the overall execution time for the program, or perhaps the user visible task within the program? -
Quickly zero all local variables?
David Heffernan replied to A.M. Hoornweg's topic in RTL and Delphi Object Pascal
It doesn't exist. You'd have to ask Embarcadero. Only they can make it happen.