Author Topic: vlax-create-object or vla-getInterfaceObject?  (Read 16702 times)

0 Members and 1 Guest are viewing this topic.

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: vlax-create-object or vla-getInterfaceObject?
« Reply #15 on: December 13, 2010, 12:43:12 PM »
You can see Reini Urban's reply here

Judging by his reply, it seems he recommends vlax-get-or-create-object, am I right?

Your English is certainly better than mine...
By my side, I'm not an ActiveX specialist and should say they're equivalent.
Speaking English as a French Frog

Lee Mac

  • Seagull
  • Posts: 12912
  • London, England
Re: vlax-create-object or vla-getInterfaceObject?
« Reply #16 on: December 13, 2010, 12:47:20 PM »
Your English is certainly better than mine...

:-D

By my side, I'm not an ActiveX specialist and should say they're equivalent.

That seems to make sense - both options appear to function equally well.  :-)

JohnK

  • Administrator
  • Seagull
  • Posts: 10625
Re: vlax-create-object or vla-getInterfaceObject?
« Reply #17 on: December 13, 2010, 03:21:39 PM »
I dont mean to rain on your parade (cause more confusion) but I feel I should mention that when you create these helper functions you are (or could be) inadvertently opening a can of worms usually called; "Nested references" (not xrefs, object refs). This relates to the releasing of objects--there is no real information on "how" or "when" to release objects-. Let me open this can of worms as slowly as possible (because i know im going to get yelled at and looked at like an idiot for this)...

When developing in Visual Lisp you are "supposed to" store each object reference in a variable. so...
Code: [Select]
(setq *acad* (vlax-get-acad-object))
(setq *activedoc* (vla-get-activedocument *acad*))
...

Some people--and Ive seen (and produced) many examples of this--throughout the internet.

Code: [Select]
(vla-get-layouts
  (vla-get-activedocument
    (vlax-get-acad-object)))

This is "bad" (we think) because the visual Lisp COM interface is a set of external interface tools/functions/etc. and/therefore if you use these nested object references you could be/are essentially throwing away a "copy" of the interface object...*sigh*...*frustrated* I wish I can explain what is in my mind better then this. ...when you repeat calls to these external interface tools you can be creating extra overhead processing. Basically, the user (programmer) is supposed to decide when to "release" the object (I put RELEASE in quotes, because the act of releasing an object is only a request really).

Ive seen many, MANY "rules" about when and when not to release objects--The act of releasing/getting the activedoc, modelspace, etc. are even more confusing because there isnt usually any "change" done on them--but no real answer on when to.

The long and short of all this is that you "should" try and use any global symbols if you can if you are using any of the VLA-GETxx stuff IMHO.

So you could/should/whatever do something like:

Code: [Select]
(vla-getinterfaceobject (or *acad* (setq *acad* (vlax-get-acad-object))) "shell.application")
;;because i know no one will listen to me unless I use OR

or

Code: [Select]
(setq *acad*
      (cond
        (*acad*)
        ((vlax-get-acad-object)))
      )

(vla-getInterfaceObject *acad* "Shell.Application")

In these helper functions. Or you should just not that these are to be used as examples not necessarily use outright.

Thats it for now, I'll let someone else chime in to finish this up.
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

Lee Mac

  • Seagull
  • Posts: 12912
  • London, England
Re: vlax-create-object or vla-getInterfaceObject?
« Reply #18 on: December 13, 2010, 03:26:59 PM »
I take your point - and I've seen it discussed many many times. After reading many of the other threads, I was under the impression that objects falling under the AutoCAD Object Model hierarchy such as the Application & Document objects will be taken care of by AutoCAD; whereas those created (such as the FSO or WSH) should be released.

There are many mixed opinions over this if I remember.

EDIT: Oh - and with using Globals you have the issue with null interface pointers wherein a global variable pointing to say the Application Object is used, released somewhere, then, due to the variable not being nil, referenced as a null interface pointer.

JohnK

  • Administrator
  • Seagull
  • Posts: 10625
Re: vlax-create-object or vla-getInterfaceObject?
« Reply #19 on: December 13, 2010, 03:39:44 PM »
yes they "should be" but only for sure when the application (AutoCAD) is shutdown and not even then for sure because AutoCAD may not give up all its memory. Another aspect is when you then take into account that each open document (in a MDI environment) has its own name-space...

yes, see! now you can appreciate/understand that this is a BIG can of worms.

Taking my point and applying it are two different things; what are you going to do (allow overhead)? Its a big decision because people are going to blindly use your stuff on their production drawings. This is why its a lot easier for me (and others) to write my (our) own version sometimes instead of "correcting" someone else's half-cocked application--but then again, sometimes i (we are) am in a rush and i (we) just cut and paste-.

Big topic isn't it?
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

Lee Mac

  • Seagull
  • Posts: 12912
  • London, England
Re: vlax-create-object or vla-getInterfaceObject?
« Reply #20 on: December 13, 2010, 03:51:33 PM »
Whether or not people use my stuff blindly on production drawings is up to them - the risks of doing so should be obvious with any code. I suppose the safest way would be to create/release everything you need within the subfunction to make it a stand-alone function without requiring the user to consider what needs to be global or released.

You mention how, even when the release function is called, the object may not entirely be released from memory - but can this actually be avoided? How else does one completely release any object?

In other cases, I sometimes require the objects as arguments for the function, hence leaving it up to the user to make the decision of whether or not to do the releasing  :lol:

This is why its a lot easier for me (and others) to write my (our) own version sometimes instead of "correcting" someone else's half-cocked application--but then again, sometimes i (we are) am in a rush and i (we) just cut and paste-.

Not sure what you mean by that to be honest - could you elaborate?

JohnK

  • Administrator
  • Seagull
  • Posts: 10625
Re: vlax-create-object or vla-getInterfaceObject?
« Reply #21 on: December 13, 2010, 03:55:18 PM »
releasing: in all the languages i know releasing is only a request.

Objects as arguments: yes that is a very good way to build helper functions. I highly recommend that method.

example: I'll build one.
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: vlax-create-object or vla-getInterfaceObject?
« Reply #22 on: December 13, 2010, 04:04:34 PM »
I apologize for not having the links but I collected this many years ago.

Code: [Select]
David McNiven   Sep 15 1999, 12:00 am   

Tony
I got them this way:
 (setq *AcadObj* (vlax-get-Acad-Object)
         *AcadDoc* (vla-get-ActiveDocument *AcadObj*)
           *PrefCol* (vla-get-Preferences *AcadObj*)
         *MenuCol* (vla-get-MenuGroups *AcadObj*)
            *LayCol* (vla-get-Layers *AcadDoc*)
       *LayoutCol* (vla-get-Layouts *AcadDoc*)
  )
Dave Mc



 Tony Tanzillo   Sep 16 1999, 12:00 am     

David - All of those collections are all part
of an aggregation, which generally means they
do not need to be explicitly released (using
vlax-release-object).


In other words, if you didn't explicitly create
the objects (in this case, AutoCAD is creating
them), then you shouldn't have to release them.


Of course, you could try (vlax-release-object)
on all of those VLA-Objects, and if you still
get the AV, that would categorically rule them
out as being the problem.   


My guess is that its a bug in VLISP, but I can't
really tell you very much without seeing the
code.


One thing you might try is putting a few (princ)
calls in the file you're loading to see exactly
where it's failing.
 


===========================================


From: Tony Tanzillo
Date: Feb/26/00 - 22:39 (GMT)
Some COM objects are referenced-counted, and others are not. IOW, the
lifetime of a COM object is not necessarily always controlled by its
reference count. In those cases, and/or depending on how a COM object was
created, it may not destroy itself when all references to it are released.
This is the case with both AutoCAD's application and document objects. The
Application object represents ACAD.EXE The document object represents an
open drawing. When you release either of them and there are no more
references, they don't get 'destroyed' (e.g., the drawing doesn't close, and
AutoCAD does not terminate). The COM wrappers for each of them also do not
seem to be destroyed either, and you can verify this by watching your system
memory usage after using (vlax-release-object) on them. You need to
'explicitly release' (excuse me for paraphrasing myself), objects which you
explicitly create, and/or objects that destroy themselves when they're
released, but there is little point to doing that with these two particular
objects since it doesn't really have any effect. From what I can tell, other
AutoCAD objects which have COM 'wrappers' that are created by AutoCAD
on-demand (e.g., the first time you reference a drawing entity, only then
does AutoCAD create a COM wrapper for it), you can release them, and the
memory used by their COM wrappers will be released, but if your inteniton is
to work with those objects frequently, then it may be preferable to not
release them, so their COM wrappers remain in memory, and do not have to be
re-created again, the next time they're needed. In the previous thread where
I mentioned that you need to explicitly release objects, I was generally
referring to objects that you create, or those which are created for you by
another ActiveX object as part of an aggregation. These generaly include
objects created using (vla-getinterfaceobject). In that case, when you
explicil8y release the COM object, it will destroy itself provided there are
no other references to it, and if there are no other referenced COM objects
in the same DLL server that houses the released object, then the DLL server
will be unloaded.







No. Visual LISP might release them for you the next time
it performs a garbage collection, but releasing objects
might have side effects that your application may depend
on, which means that you should always release them when
you're done using them.

Another problem that occurs with AutoCAD entities, is that
certain actions taken by the user can invalidate the COM
wrapper for an entity (because the underlying object type
has changed). In order to get AutoCAD to create a new COM
wrapper that corresponds to the correct type of entity, it
must first release the existing one, so waiting for Visual
LISP to get around to doing that is not good.




Your variable is not 'empty' as Frank put it, because
'emtpy' only applies to variants, not objects.
A null interface pointer is equivalent to a VB object
variable assigned to Nothing.


You may be calling (vlax-release-object) more than once
on a given object. That's the only way the variable can
be cleared.


Try using this in place of (vlax-release-object):


  (defun release-object (obj)
     (if (not (vlax-object-released-p obj))
        (vlax-release-object obj)
     )
  )



 Luis Esquivel   Sep 15 2003, 10:09 am   

This have been an issue before to many times...

I just release those objects created via:

vlax-create-object
vlax-get-or-create-object
vla-getinterfaceobject

AutoCAD takes care of the others ones...

 
 
Tony Tanzillo   Sep 15 2003, 3:10 pm   

There can be problems if you are holding a pointer
to an entity whose type can be changed by an editing
command (e.g., break a circle changes it to an ARC),
so it doesn't hurt to release objects when you don't
need them any longer. Unfortunately, that practice can
turn Visual LISP code into spaghetti, especially if
cleanup/error handling are factored into the equation.



 Tony Tanzillo   Sep 15 2003, 5:40 pm   

"Devin"
> If I have multiple pointers to an object and I release the object, is it
> released from all pointers?


Yes, releasing an object causes all variables that
reference the same vla-object to become disconnected
from the object:

Command: (setq e (vlax-ename->vla-object (entlast)))
#<VLA-OBJECT IAcadPViewport 02840914>


Command: (setq e2 e e3 e)
#<VLA-OBJECT IAcadPViewport 02840914>

Command: (vlax-release-object e)
0

Command: !e2
#<VLA-OBJECT 00000000>

Command: !e3
#<VLA-OBJECT 00000000>


Doug Broad   Sep 15 2003, 5:40 pm 

Both Tony and Luis are correct.

Tony shows a special case where all the symbols are bound to
the same pointer.

The same thing would not be true of the following
(setq e (car (entsel))
         a (vlax-ename->vla-object e)
         b (vlax-ename->vla-object e)
         c (vlax-ename->vla-object e))
(vlax-release-object a)
2
!a
#<VLA-OBJECT 00000000>
!b
#<VLA-OBJECT IAcadLine 0182c454>
!c
#<VLA-OBJECT IAcadLine 0182c454>
(vlax-release-object b)
1
!b
#<VLA-OBJECT 00000000>
!c
#<VLA-OBJECT IAcadLine 0182c454>
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

JohnK

  • Administrator
  • Seagull
  • Posts: 10625
Re: vlax-create-object or vla-getInterfaceObject?
« Reply #23 on: December 13, 2010, 04:27:34 PM »
Ah very cool CAB. I had that doc at one time but lost it LONG time ago.  Read what CAB posted then apply that knowledge to this...

<trimmed up a bit>

Here is a fancy helper function to be used as noted in the comments I found out on the internet (lets say its yours and you spent an hour making it pretty and nice for me to use). I will show you how to use your helper function the "correct" way (grain of salt to: you--im exaggerating-.)

Code: [Select]
(defun VL:Make-Layer (Name / )
  ;; Visual Lisp : Make Layer
  ;; given a layer name this will create a layer.
  ;;
  ;; EX: (vl:make-layer "MyNewLayer")
    (vla-add
      (vla-get-layers
        (vla-get-ActiveDocument
          (vlax-get-acad-object)
          )
        )
      Name
      )
    )

A seasoned Auto/visual lisp programer will only use this as an example to build his or her own. For example, All I care about (or use this helper function for) is that I need to issue the ADD method on the LAYERS object. I can drill down the object model in my own way and use my own GLOBALS for example and decide to release or not on my own.

Code: [Select]
(defun my-fancy-app ( / )

  (setq *acadobject*
          (cond
            (*acadobject*)
            ((vlax-get-acad-object)))
        *activedocument*
          (cond
            (*activedocument*)
            ((vla-get-activedocument *acadobject*)))
        *layers*
           (cond
             (*layers*)
             ((vla-get-layers *activedocument* *acadobject*)))
        )
  (vla-add *layers* "MyNewLayer")
  ; ... other stuff

  ; ... release stuff

  ; ... garbage collect
  (gc)
  (princ)
 )

This is how *I* would use your helper function.
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

Lee Mac

  • Seagull
  • Posts: 12912
  • London, England
Re: vlax-create-object or vla-getInterfaceObject?
« Reply #24 on: December 13, 2010, 05:10:13 PM »
Hmmm... I'd be inclined to disagree with that. Surely the whole idea of a subfunction is to compartmentalise the program into blocks of code. Knowing that a sub is correctly written and understanding the methods it utilises, all a developer would require is the function arguments and returns - and, from then on, the minor details of exactly how the sub accomplishes its goal needn't be recreated. Why create subfunctions just to rip them apart for an application?

Here is how *I* would formulate the example:

Code: [Select]
(defun AddItemtoCollection ( collection item / object )
  (if
    (vl-catch-all-error-p
      (setq object
        (vl-catch-all-apply 'vla-item
          (list collection item)
        )
      )
    )
    (vla-add collection item)
    object
  )
)

[ Although, perhaps not really applicable, as vla-add doesn't actually error if the item is already present, but it illustrates the point ]

I agree with the method of supplying subs with the objects on which they operate, however, with regard to the functions in the first post, I would disagree with this approach and rather use the subs themselves to create the Shell Object. In this way one can use these subs safe in the knowledge that, where it actually does matter to release such objects, the Shell Object is created and released in the proper manner.
« Last Edit: December 13, 2010, 05:18:17 PM by Lee Mac »

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: vlax-create-object or vla-getInterfaceObject?
« Reply #25 on: December 13, 2010, 05:22:19 PM »
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

JohnK

  • Administrator
  • Seagull
  • Posts: 10625
Re: vlax-create-object or vla-getInterfaceObject?
« Reply #26 on: December 13, 2010, 05:34:09 PM »
Lee, i think you missed my point; this isnt a pissing contest. Do what you want; I'm sick of trying to help now.

TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: vlax-create-object or vla-getInterfaceObject?
« Reply #27 on: December 13, 2010, 06:59:10 PM »
And then there is this: http://www.theswamp.org/index.php?topic=2005.0

I was wondring where that one was :)

This discussion has happened each 6 months or so for the last 15 odd years (since Basis developed Vital Lisp)




kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.