Author Topic: vla-setxrecorddata... store enames... variant type 8212?  (Read 2850 times)

0 Members and 1 Guest are viewing this topic.

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
vla-setxrecorddata... store enames... variant type 8212?
« on: November 27, 2015, 04:37:47 PM »
I am trying to use vla-setxrecorddata to store enames in dictionaries.
For BricsCAD 32 bit I have used this function to get the required variant (type 8195):
Code - Auto/Visual Lisp: [Select]
  1. (defun _Conv_Object_To_Variant (object)
  2.   (vlax-make-variant
  3.       (vlax-make-safearray vlax-vblong '(0 . 1))
  4.       (list (vla-get-objectid object) 0)
  5.     )
  6.   )
  7. )

But for BricsCAD V16 64 bit I appear to need a variant of the 8212 type.
Does anybody know how to do create this?

Lee Mac

  • Seagull
  • Posts: 12928
  • London, England
Re: vla-setxrecorddata... store enames... variant type 8212?
« Reply #1 on: November 27, 2015, 06:58:08 PM »
Some experimentation in 64-bit AutoCAD:

Code - Auto/Visual Lisp: [Select]
  1. (defun c:test ( / ent )
  2.     (if (setq ent (car (entsel)))
  3.         (dictadd
  4.             (dictadd (namedobjdict) "TestDictionary"
  5.                 (entmakex
  6.                    '(
  7.                         (000 . "DICTIONARY")
  8.                         (100 . "AcDbDictionary")
  9.                     )
  10.                 )
  11.             )
  12.             "TestXRecord"
  13.             (entmakex
  14.                 (list
  15.                    '(000 . "XRECORD")
  16.                    '(100 . "AcDbXrecord")
  17.                     (cons 340 ent)
  18.                 )
  19.             )
  20.         )
  21.     )
  22. )

Code - Auto/Visual Lisp: [Select]
  1. _$ (dictsearch (cdr (assoc -1 (dictsearch (namedobjdict) "TestDictionary"))) "TestXRecord")
  2.  
  3. (
  4.     (-1 . <Entity name: 7ffff709850>)
  5.     (0 . "XRECORD")
  6.     (5 . "395")
  7.     (102 . "{ACAD_REACTORS")
  8.     (330 . <Entity name: 7ffff709840>)
  9.     (102 . "}")
  10.     (330 . <Entity name: 7ffff709840>)
  11.     (100 . "AcDbXrecord")
  12.     (280 . 1)
  13.     (340 . <Entity name: 7ffff709720>)
  14. )

Code - Auto/Visual Lisp: [Select]
  1. _$ (setq xrc (vlax-ename->vla-object (cdr (assoc -1 (dictsearch (cdr (assoc -1 (dictsearch (namedobjdict) "TestDictionary"))) "TestXRecord")))))
  2. #<VLA-OBJECT IAcadXRecord 0000000028ffd328>
  3. _$ (vla-getxrecorddata xrc 'typ 'val)
  4. nil
  5. _$ (vlax-safearray->list val)
  6. (#<variant 8195 ...>)
  7. _$ (vlax-safearray->list (vlax-variant-value (car (vlax-safearray->list val))))
  8. (-9398496 -53949612)
  9. _$ (mapcar 'int32->hex (vlax-safearray->list (vlax-variant-value (car (vlax-safearray->list val)))))
  10. ("FF709720" "FCC8CB54")

I hope this helps.
« Last Edit: November 27, 2015, 07:02:57 PM by Lee Mac »

owenwengerd

  • Bull Frog
  • Posts: 451
Re: vla-setxrecorddata... store enames... variant type 8212?
« Reply #2 on: November 28, 2015, 12:15:28 AM »
The vlax-vblong type is just 32 bits, but an object ID requires 64 bits. The element type should be 20 for a 64-bit signed integer value, but (vlax-make-safearray) rejects that type. Maybe type 9 would work? In any case, please make sure this problem reported.

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: vla-setxrecorddata... store enames... variant type 8212?
« Reply #3 on: November 28, 2015, 05:51:49 AM »
@ Lee:
Thank you for testing this.

Here are the results from BC16 64 bit:

Code - Auto/Visual Lisp: [Select]
  1. (dictsearch (cdr (assoc -1 (dictsearch (namedobjdict) "TestDictionary"))) "TestXRecord")
  2. =>
  3. (
  4.   (-1 . <Entity name: 171bd980>)
  5.   (0 . "XRECORD")
  6.   (5 . "B3")
  7.   (102 . "{ACAD_REACTORS")
  8.   (330 . <Entity name: 171bd640>)
  9.   (102 . "}")
  10.   (330 . <Entity name: 171bd640>)
  11.   (100 . "AcDbXrecord")
  12.   (280 . 1)
  13.   (340 . <Entity name: 171c6680>)
  14. )

Code - Auto/Visual Lisp: [Select]
  1. (setq xrc (vlax-ename->vla-object (cdr (assoc -1 (dictsearch (cdr (assoc -1 (dictsearch (namedobjdict) "TestDictionary"))) "TestXRecord")))))
  2. => #<VLA-OBJECT IAcadXRecord 000000001716C7E0>
  3. (vla-getxrecorddata xrc 'typ 'val)
  4. => nil
  5. (vlax-safearray->list val)
  6. => (#<variant 8212 ...>)
  7. (car (vlax-safearray->list val))
  8. => (#<variant 8212 ...>) ; This is the ename variant value I am trying to create.
  9. (vlax-safearray->list (vlax-variant-value (car (vlax-safearray->list val))))
  10. => (387737216 0)
  11. (mapcar '_Math_Dec_To_Hex (vlax-safearray->list (vlax-variant-value (car (vlax-safearray->list val)))))
  12. => ("171C6680" "0")

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: vla-setxrecorddata... store enames... variant type 8212?
« Reply #4 on: November 28, 2015, 05:53:15 AM »
@ Owen:
Thanks for your suggestion, but sadly using type 9 does not work. I will send in a support request.

Lee Mac

  • Seagull
  • Posts: 12928
  • London, England
Re: vla-setxrecorddata... store enames... variant type 8212?
« Reply #5 on: November 28, 2015, 09:17:05 AM »
You're welcome roy.

When testing, I was unsure of the significance of the second item in the safearray (-53949612); it obviously seems as though the 64-bit Object ID is stored as two 32-bit integers, but after some thought, I couldn't seem to work out how they should be recombined.  :-(

TMoses

  • Guest
Re: vla-setxrecorddata... store enames... variant type 8212?
« Reply #6 on: November 29, 2015, 11:24:11 AM »
Dear All,

indeed, using type 9 (IDispatch, the VLA object) should work to set XRecord data ...
I will verify + fix both approaches :
- allow VT type 9 to use IDispatch (which will cause the setXRecordData to finally use the object's ObjectId)
- allow VT type 20 (and add symbol vlax-vbInt64 for it)

Lee's tests under AutoCAD are indeed confusing : as 1 entity/object is set, it can never return 2 values  :-)
How shall anyone know whether those are truly 2 entities/objects, or only 1, with "splitted" notation ?  :-)

Meaning, that AutoCAD approach is obviously useless ... likely never fixed with 64 bit AutoCAD/Lisp ...

I will keep you updated here ... and thanks for the good testing code !

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: vla-setxrecorddata... store enames... variant type 8212?
« Reply #7 on: November 29, 2015, 01:05:59 PM »
Within the context of Xrecords both the group code (key) and the 'size' of the array value can be used to identify objects.
Code - Auto/Visual Lisp: [Select]
  1. (vla-getxrecorddata object 'keyLst 'valueLst)
  2.   '(lambda (key value)
  3.     (cons
  4.       key
  5.       (if (> vlax-vbarray (vlax-variant-type value))
  6.         (vlax-variant-value value)
  7.         (if (= 3 (length (setq value (vlax-safearray->list (vlax-variant-value value)))))
  8.           ;; Point:
  9.           value
  10.           ;; Ename:
  11.           (if
  12.             (setq value
  13.               (_Sys_Apply 'vla-objectidtoobject (list (vla-get-database object) (car value)))
  14.             )
  15.             (vlax-vla-object->ename value)
  16.           )
  17.         )
  18.       )
  19.     )
  20.   )
  21.   (vlax-safearray->list keyLst)
  22.   (vlax-safearray->list valueLst)
  23. )

TMoses

  • Guest
Re: vla-setxrecorddata... store enames... variant type 8212?
« Reply #8 on: November 29, 2015, 04:04:21 PM »
There is a strange misbehaviour in (vla-GetXRecordData) and (vla-SetXRecordData) in AutoCAD AutoLISP, when it comes to ObjectId/Ename values :

in
(vla-SetXRecordData), the ObjectId/Ename value must be specified as VLA-OBJECT (IDispatch), i.e. for 340 group code;
but in
(vla-GetXRecordData) those ObjectId/Ename objects are returned as list of 2 integers, as Lee also found;
AutoCAD provides 2 strange values,
BricsCAD provides the 1. integer as true ObjectId integer value (even in 64 bit), and the second is 0 ...

So there is no need to create such identical array of integer ObjectId/Ename values, but it must be of VLA-OBJECT (IDispatch) type.

The most natural way to return ObjectId/Ename for COM would be to use IDispatch objects, seems to be a bug in AutoCAD AutoLISP, such integers makes no sense at all in COM, and are unusable especially for external apps.
But if we would change BricsCAD LISP here, application code would get unexpected values, and it would be incompatible :-(

types array : Variant, containing a SafeArray of VT_I2 (vlax-vbInteger) type
value array : Variant, containing a SafeArray of VT_VARIANT (vlax-vbVariant) type, each item is a Variant itself, because the values can be of different types (int, string, double, ....), due to corresponding type item

here is some test code as I used to verify the behaviour :

Code: [Select]
(vl-load-com)
(setq vlaen (vlax-ename->vla-object (entlast)))
(setq dict (vla-GetExtensionDictionary vlaen))
(setq objId (vla-get-objectid vlaen))

(setq saTypes (vlax-make-safearray vlax-vbInteger '(0 . 0)))
(vlax-safearray-fill saTypes (list 340))
(setq vtTypes (vlax-make-variant saTypes))

(setq saValues (vlax-make-safearray vlax-vbVariant '(0 . 0)))
(setq vtObject (vlax-make-variant vlaen))

(vlax-safearray-fill saValues (list vtObject))
(setq vtValues (vlax-make-variant saValues))

(setq xrcd (vla-AddXRecord dict "xxx"))
(vla-SetXRecordData xrcd vtTypes vtValues)

(setq types nil values nil)

(vla-getxrecorddata xrcd 'types 'values)
(print types)
(print values)

(setq types  (vlax-safearray->list types))
(setq values (vlax-safearray->list values))

(setq val (car values))
(setq res (vlax-variant-value val))
(vlax-safearray->list res)

Nevertheless, I improved (vlax-make-variant/safearray) functions to accept the type "20" (vla-vbInt64) just for some special cases ... will be in upcoming BricsCAD.

I hope this clarifies the situation ?
many greetings to all !

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: vla-setxrecorddata... store enames... variant type 8212?
« Reply #9 on: November 30, 2015, 05:51:05 AM »
Thank you Torsten.
The obvious conclusion is that using 'Classic' Lisp is the best option when dealing with enames in Xrecords.

TMoses

  • Guest
Re: vla-setxrecorddata... store enames... variant type 8212?
« Reply #10 on: November 30, 2015, 10:02:40 AM »
Dear Roy,

yes, indeed ... at least, for retrieving referenced entities;
creating XRecords via COM seems fine ...
many greetings !