Author Topic: About read and write binary file  (Read 11854 times)

0 Members and 1 Guest are viewing this topic.

highflyingbird

  • Bull Frog
  • Posts: 415
  • Later equals never.
About read and write binary file
« on: January 14, 2011, 02:34:13 AM »
here is a routine for reading binary file to a txt file,and writing  a binary file from a txt file.

the question is :
1) why  I get different result in R2006 and R2011, it can't work in R2011,because in  "ReadBinary function"

The return value from  (vlax-safearray->list (vlax-variant-value arr))   is different. eg.
in R2006,it would be: (255 216 ........)      ----->it's what I need
in R2011,it would be: (-22785 -22824 ........)   ----->I don't know why  these numbers are larger than 255 or they are negative numbers?

2) On the (vlax-safearray->list (vlax-variant-value arr)) step, if I read a large size file, it will take a pretty long time.can I get some faster way?

Code: [Select]
(defun c:test ()
  (defun ReadBinary (FileName / stream arr)
    (setq stream (vlax-create-object "ADODB.Stream"))
    (vlax-put stream 'type 1) ;adTypeBinary
    (vlax-invoke stream 'open) ;adModeRead  =1 adModeWrite  =2 adModeReadWrite =3
    (vlax-invoke stream 'LoadFromFile filename)
    (setq Arr (vlax-invoke-method stream 'read (vlax-get stream 'SIZE)));read stream
    (vlax-invoke stream 'close)
    (vlax-release-object stream)
    (vlax-safearray->list (vlax-variant-value arr)) ;if a large size file ,it will take a long time in this step
  )
  (defun WriteBinary (FileName Array / stream)
    (setq stream (vlax-create-object "ADODB.Stream"))
    (vlax-put stream 'type 1) ;adTypeBinary
    (vlax-invoke stream 'open) ;adModeRead  =1 adModeWrite  =2 adModeReadWrite =3
    (vlax-invoke-method stream 'Write array) ;write stream
    (vlax-invoke stream 'saveToFile fileName 2) ;save
    (vlax-invoke stream 'close)
    (vlax-release-object stream)
  )

  (setq path (getfiled "Please select a binary file:" "c:/" "" 8))      ;get file path
  (setq f (open "C:\\test.txt" "W"))
  (setq data (readBinary path))
  (princ data f)
  (close F)

  ;;(setq aaa (vl-get-resource "test"))                                ;we can wrap this text file into .vlx file
  (setq f (open "C:\\test.txt" "R"))                                    ;open for read
  (setq l "")
  (while (setq s (read-line f))
    (setq l (strcat l s))
  )
  (setq array (read l))   
  (close f)                         
 
  (setq dat (vlax-make-safearray 17 (cons 0 (1- (length array)))))      ;17 for unsigned char
  (vlax-safearray-fill dat array)
  (setq bin (vlax-make-variant dat))
  (writeBinary "C:\\test.jpg" bin) ;write binary file.
)
« Last Edit: January 14, 2011, 03:40:08 AM by highflybird »
I am a bilingualist,Chinese and Chinglish.

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: About read and write binary file
« Reply #1 on: January 14, 2011, 12:52:13 PM »
Perhap this by MP may offer some insight.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: About read and write binary file
« Reply #2 on: January 14, 2011, 12:56:34 PM »
hint: ascii / unicode / oh my
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

highflyingbird

  • Bull Frog
  • Posts: 415
  • Later equals never.
Re: About read and write binary file
« Reply #3 on: January 14, 2011, 11:24:30 PM »
Perhap this by MP may offer some insight.

I knew this article,thank MP very much.
but maybe we can't  use "FileSystemObject" to create a binary file.I tested many times,failed.
so I use "Adodb.stream" , actually, In VBS,it's much faster,but in CAD, we must convert a variant to a list.It will take a long time.

the routine below works very well:
Code: [Select]
(defun ReadBinary (filename)
  (if (setq wsObj (vlax-create-object "ScriptControl"))
    (progn
      (vlax-put wsObj "language" "VBS")
      (setq str
       "Function ReadBinary(FileName)
Const adTypeBinary = 1
Dim stream, xmldom, node
Set xmldom = CreateObject(\"Microsoft.XMLDOM\")
Set node = xmldom.CreateElement(\"binary\")
node.DataType = \"bin.hex\"
Set stream = CreateObject(\"ADODB.Stream\")
stream.Type = adTypeBinary
stream.Open
stream.LoadFromFile FileName
node.NodeTypedValue = stream.Read
stream.Close
Set stream = Nothing
ReadBinary = node.Text
Set node = Nothing
Set xmldom = Nothing
End Function"
      )
      (vlax-invoke wsObj 'ExecuteStatement str)
      (setq str (vlax-invoke wsObj 'run "ReadBinary" filename))
      (vlax-release-object wsObj)
      str
    )
  )
)
(defun writeBinary (FileName buffer / wsObj str)
  (if (setq wsObj (vlax-create-object "ScriptControl"))
    (progn
      (vlax-put wsObj "language" "VBS")
      (setq str
       "Sub WriteBinary(FileName, Buf)
Const adTypeBinary = 1
Const adSaveCreateOverWrite = 2
Dim stream, xmldom, node
Set xmldom = CreateObject(\"Microsoft.XMLDOM\")
Set node = xmldom.CreateElement(\"binary\")
node.DataType = \"bin.hex\"
node.Text = Buf
Set stream = CreateObject(\"ADODB.Stream\")
stream.Type = adTypeBinary
stream.Open
stream.write node.NodeTypedValue
stream.saveToFile FileName, adSaveCreateOverWrite
stream.Close
Set stream = Nothing
Set node = Nothing
Set xmldom = Nothing
        End Sub"
      )
      (vlax-invoke wsObj 'ExecuteStatement str)
      (vlax-invoke wsObj 'run "WriteBinary" Filename buffer)
      (vlax-release-object wsObj)
      (princ)
    )
  )
)
« Last Edit: January 14, 2011, 11:29:39 PM by highflybird »
I am a bilingualist,Chinese and Chinglish.

SOFITO_SOFT

  • Guest
Re: About read and write binary file...Very interesting !!!
« Reply #4 on: January 17, 2011, 04:37:58 PM »
Hello everyone:
Very interesting these two functions. And very useful.
I almost went crazy about reading in binary files SLD.
A doubt assailed me:
What type of variable is "BUFFER" In "writeBinary""?
The variable "str" returned by "ReadBinary" contains something like:
"42 BE 4D 30 00 00 00 00 00 00 36 04 00 00 28 00 ...." no spaces. Are hex values with lower case letters?
Is valid a "string" like variable "BUFFER"?
I work in A2008 with wXP.
Thanks in advance.
Greetings from Madrid.
PS: another surprise "(ReadBinary "c: \ \ wapa.bmp")" is not accepted. Only "c: / wapa.bmp. " !!!

highflyingbird

  • Bull Frog
  • Posts: 415
  • Later equals never.
Re: About read and write binary file...Very interesting !!!
« Reply #5 on: January 17, 2011, 07:07:45 PM »
Hello everyone:
Very interesting these two functions. And very useful.
I almost went crazy about reading in binary files SLD.
A doubt assailed me:
What type of variable is "BUFFER" In "writeBinary""?
The variable "str" returned by "ReadBinary" contains something like:
"42 BE 4D 30 00 00 00 00 00 00 36 04 00 00 28 00 ...." no spaces. Are hex values with lower case letters?
Is valid a "string" like variable "BUFFER"?
I work in A2008 with wXP.
Thanks in advance.
Greetings from Madrid.
PS: another surprise "(ReadBinary "c: \ \ wapa.bmp")" is not accepted. Only "c: / wapa.bmp. " !!!

This is an example:

Code: [Select]
(defun C:test ()
  (if (setq name (getfiled "Select a file" "C:/" "" 8))
    (progn
      (setq buff (readbinary name))
      (setq file (open "c:\\1.txt" "W"))
      (princ buff file)
      (close file)
      (writeBinary "C:\\test.bmp" buff)
      (princ)
    )
  )
)
« Last Edit: January 17, 2011, 07:12:28 PM by highflybird »
I am a bilingualist,Chinese and Chinglish.

SOFITO_SOFT

  • Guest
Re: About read and write binary file
« Reply #6 on: January 18, 2011, 06:27:38 AM »
Hello
Method is extremely useful .... very instant. I tested with files up to 2 Mb and is doing well.
Thank you very much for the explanation ...
Greetings.

chlh_jd

  • Guest
Re: About read and write binary file
« Reply #7 on: April 30, 2014, 04:21:17 PM »
Test though ACAD2015 , May be
Code - Auto/Visual Lisp: [Select]
  1. ;;  SS:ReadBinaryStream V2.0  
  2. ;;  
  3. ;;  function : Read binarystream from file(full path) by given charset , return a List or a String .
  4. ;;  
  5. ;;  Args:
  6. ;;  file -- file name with full path , The file size must be less than amount of memory can be used for the current AUTOCAD .
  7. ;;          
  8. ;;  char -- charset name , it must register in your system , see the Windows registry sub-key in \\HKEY_CLASSES_ROOT\\MIME\\Database\\Charset
  9. ;;              such as "unicode","ascii","us-ascii","chinese","GB2132", etc.
  10. ;;          nil & "Unicode" , allways return a list like by vlisp function Read-char .
  11. ;;          Oterwise , the char will be used to convert the stream into text string .
  12. ;;          
  13. ;;  pos  -- position for start read byte , first start pos is 0 , second is 1,
  14. ;;                   for Bigfont-Char it maybe use two bytes , if so the second text start pos is 2 , 4 ... 2n .
  15. ;;  len  -- Numbits for read or readtext , if nil or beyond the size , will be set to suit Maximum value .
  16. ;;  
  17. ;;  Returns -- if char is nil or "Unicode" , returns a ascii code list ;after Acad2008 , The system expansion Charset beyond the 256 limit ,
  18. ;;                      so it may return number like 18714 or -18918(after Acad2013) ,for this case , you can use (rem 18714 256)
  19. ;;                      or (rem (+ 256(rem -18714 256)) 256) to get the ascii code like old version .
  20. ;;             if char is not nil and "Unicode" , and it's supported in your window system , returns a string .
  21. ;;  
  22. ;;  by GSLS(SS) 10.23-2011 ~
  23. ;;--------------------------------------------------------------------------;;
  24. ;; Refrence :
  25. ;;   adodb.stream      from   http://baike.baidu.com/link?url=HkCWIQo1pSmTMN76tTipNkSUR5O_s7_8ctpH_XXuo06y2qhd-TCAkCCuxDOtNi55zA5V9eTPO4fobMbeYDNjHK
  26. ;;   Microsoft Data Access Components
  27. ;;                     from   http://en.wikipedia.org/wiki/Microsoft_Data_Access_Components
  28. ;;   Nonsmall's        from   http://bbs.mjtd.com/forum.php?mod=viewthread&tid=78782&extra=page%3D2%26filter%3Dtypeid%26typeid%3D110&page=1
  29. ;;   Michale's         from   http://www.theswamp.org/index.php?topic=17465.0
  30. ;;   LeeMac's          from   http://www.theswamp.org/index.php?topic=39814.0
  31. ;;   Highflybird's     from   http://www.theswamp.org/index.php?topic=36656.0
  32. ;;                            this vbs can't run in my used case : ACAD2011 Win7 64Bit.  
  33. ;;--------------------------------------------------------------------------;;
  34. ;; Method of Adodb.Stream object .                                          ;;
  35. ;;    Open ,  Close ,  Write ,  WriteText , Read ,  ReadText,               ;;
  36. ;;    Flush , CopyTo , Cancel , SkipLine,   SetEOS                          ;;
  37. ;; Property of Adodb.Stream object .                                        ;;
  38. ;;     LineSeparator,   SaveToFile, LoadFromFile , Charset ,                ;;
  39. ;;     Size ,  Position , Type , State , Mode , EOS ,                       ;;
  40. ;;--------------------------------------------------------------------------;;
  41. ;; e.g.  (SS:ReadBinaryStream (findfile "gslsshp.shx")  "us-ascii"  23  32) -->
  42. ;;        "\032\010\000\010\000\001\000\010\000\022\000HELL\000\r\031^d\035z6q(`\000\000\000EOF"
  43. ;;       (SS:ReadBinaryStream (findfile "gslsshp.shx") "Unicode" 23 4)--> '(18714 18824 18688 18824)  '(-18918 -18808 -18944 -18808)--of ACAD2015
  44. ;;       (SS:ReadBinaryStream (findfile "gslsshp.shx") nil 23 4)--> '(18714 18824 18688 18824)
  45. ;;       (SS:ReadBinaryStream (findfile "gslsshp.shx") "ascii" 23 4)-->"\032\010\000\010"
  46. (defun SS:ReadBinaryStream
  47.        (file char pos len / adostream ret size str)  
  48.  ;_(setq file "gslsshp.shx"  file (findfile file)  char "us-ascii" pos 0 len nil)
  49.  ;_(setq file "gslsshp.shx"  file (findfile file)  char nil pos 23 len nil)
  50.   (if (and (findfile file) ;_check file exists , No rebuild file name by (findfile file) , because it maybe not you want truely .
  51.            (setq adostream (vlax-create-object "ADODB.Stream")) ;_check Adodb.Stream Object created .
  52.            )
  53.     (progn
  54.       (setq ret
  55.              (vl-catch-all-apply
  56.                (function
  57.                  (lambda nil
  58.                    (vlax-put adostream (quote Type) 1)
  59.  ;_Type --   The Type  property is to read / write only when the current postion located
  60.  ;_        at the beginning  (Position 0) of stream ,   at other location is read-only.
  61.  ;_          The default value is adTypeText. However, if the binary data was originally
  62.  ;_        written in a new empty Stream, Type will be changed to adTypeBinary.
  63.  ;_         ***  adTypeBinary =1 adTypeText =2 ***
  64.                    (vlax-invoke adostream (quote Open))
  65.  ;_Open -- Stream.Open Source, Mode, OpenOptions, UserName, Password
  66.  ;_   Source -- Optional. Variant value that specifies Stream data source. Source may contain
  67.  ;_                     an absolute URL string that points to the existing nodes of the well-known tree structure
  68.  ;_                     (such as email or file system).  Use URL keyword ("URL = http://server/folder") to specify the URL.
  69.  ;_                     In addition, Source may also contain open the Record object reference to the object to open the Record
  70.  ;_                     associated with the default stream. If not specified Source, Stream will be instantiated and open,
  71.  ;_                     by default it is not associated with the underlying source.
  72.  ;_          
  73.  ;_     Mode    -- Optional. ConnectModeEnum value that specifies Access Mode (for example, read / write or read-only) of the gotten Stream .
  74.  ;_                     The default value is adModeUnknown. If Mode is not specified, it is inherited source Stream Variant.
  75.  ;_                     E.G, if you open the source Record in read-only mode, then Stream will also be open by read-only mode in default case .
  76.  ;_             *** adModeRead =1  adModeReadWrite =3   adModeRecursive =4194304   adModeShareDenyNone =16  adModeShareDenyRead =4
  77.  ;_                 adModeShareDenyWrite =8   adModeShareExclusive =12  adModeUnknown =0  adModeWrite =2 ***
  78.  ;_          
  79.  ;_ OpenOptions -- Optional. StreamOpenOptionsEnum value that's default value is -1 .
  80.  ;_             ***  adOpenStreamAsync =1   adOpenStreamFromRecord =4  adOpenStreamUnspecified=-1 ***
  81.  ;_   UserName  -- Optional. String value that contains (when necessary) the identity of the user to access a Stream object.
  82.  ;_   Password  -- Optional. String value that contains (when required) to access a Stream object password.
  83.                    (vlax-invoke-method
  84.                      adostream
  85.                      (quote LoadFromFile)
  86.                      file)
  87.  ;_LoadFromFile --  Load the contents of an existing file into the Stream, or upload the contents of the lacal file to the server .
  88.  ;_                 FileName can contain any UNC format valid path and name . If the specified file does not exist, a runtime error will occur.
  89.  ;_                 Stream object must be open before calling LoadFromFile . This method does not change the binding Stream object ,
  90.  ;_                     it is still bound to the  object specified by URL of the  original open Stream . LoadFromFile overwrite the current
  91.  ;_                     contents of the Stream object  with the data read from the file .
  92.                    (setq size (vlax-get adostream (quote Size))) ;_get size
  93.                    (if (and (numberp pos) (< 0 pos size));_check pos(position) suitable
  94.                      (setq pos (fix pos))
  95.                      (setq pos 0))
  96.                    (if (and (numberp len) (< 0 len size));_check len(length)  suitable
  97.                      (setq len (min len (- size pos)))
  98.                      (setq len (- size pos)))
  99.                    (vlax-put adostream (quote Position) pos)
  100.  ;_Position -- For read-only Stream object, If the Position value you set exceed the Size of  Stream ,
  101.  ;_              ADO will not return an error. This does not change the size of the Stream,
  102.  ;_              Stream will not change the content in any way. However, you should avoid this operation
  103.  ;_              because it may produce meaningless Position value.
  104.                    (vlax-invoke-method
  105.                      adostream
  106.                      (quote Write) ;_overite stream contents by binary though Unicode Charset from memory .
  107.  ;_Write -- Write the binary data to Stream object . method : Stream.Write Buffer
  108.  ;_     Buffer -- Variant, contains a bytes safearray to be written.
  109.  ;_         The specified  bytes written to Stream object, are no space between eachother .
  110.  ;_         Position is set to  1+ byte of the writen data . Write method does not cut off the flow of the remaining data.
  111.  ;_         If you want to cut these bytes, call SetEOS.
  112.  ;_         If you write more than the current EOS position, Stream's Size will increase to include the new byte,
  113.  ;_            EOS will also be moved to the last byte of new Stream  .
  114.                      (car
  115.                        (list (setq ret (vlax-invoke-method
  116.                                          adostream
  117.                                          (quote Read)
  118.  ;_ Read -- Reads the specified number of bytes or whole from the Stream object and return the Variant .
  119.  ;_             specified number of bytes  read from binary Stream object . Variant = Stream.Read ( NumBytes )
  120.  ;_   NumBytes -- optional. default value is adReadAll .
  121.                                          len)) ;_read binary
  122.                              (vlax-put adostream (quote position) 0) ;_reset position to 0
  123.                              ))) ;_end new stream
  124.                    (if
  125.                      (or
  126.                        (null char);_check charset
  127.                        (and (eq (type char) (quote STR))
  128.                             (eq (strcase char) "UNICODE"));_equal default
  129.                        (null
  130.                          (member
  131.                            char ;_(setq char "us-ascii")
  132.                            (vl-registry-descendents
  133.                              "HKEY_CLASSES_ROOT\\MIME\\Database\\Charset")) ;_check whether character set is supported in system .
  134.                          )) ;_dermine return ascii list or string
  135.                       nil ;_no rebuild ret .
  136.                       (setq ret
  137.                              (cadddr
  138.                                (list
  139.                                  (vlax-put adostream (quote position) 0)
  140.                                  (vlax-put adostream (quote type) 2) ;_set type adTypeText
  141.                                  (vlax-put adostream (quote charset) char) ;_set char
  142.  ;_ Charset --  Specifies the character set used to convert the text contents of Stream .
  143.  ;_              Such as , "Unicode" , "ascii" , "iso-8859-1" ,"Windows-1252",etc. .
  144.  ;_              For systems supported character set , see the Windows registry sub-key in \\HKEY_CLASSES_ROOT\\MIME\\Database\\Charset .
  145.  ;_          
  146.  ;_             For text Stream object , the text object is stored as Unicode. The data read from the Stream is converted by the character
  147.  ;_             set of the specified Charset property. Similarly, to write the data into the Stream object, the character set is specified to  Unicode .
  148.  ;_
  149.  ;_             For open Stream, it's current Position shall be at the beginning of located Stream (0) , so as to set Charset.
  150.  ;_             Charset only used with text Stream object (Type of adTypeText) together. If Type is adTypeBinary, this property is ignored.        
  151.                                  (vlax-invoke
  152.                                    adostream
  153.                                    (quote ReadText)
  154.                                    len) ;_ReadText
  155.  ;_ ReadText -- Reads the specified number of characters from a text Stream object . Method :  Stream.ReadText ( NumChars ) .
  156.  ;_               NumChars is Optional , Default value is adReadAll , If NumChar over the remaining number of characters in the stream,
  157.  ;_               will only return the remaining characters; Sring read is not consistent with the NumChar filled to a specified length;
  158.  ;_               If there is no remaining characters can be read, it will return a value of Null variant.
  159.  ;_             ***ReadText not be used to read backwards.
  160.  ;_             ReadText method used with text stream (Type of adTypeText=2) . For a binary stream, please use Read.
  161.                                  (setq STR T)
  162.                                  ))))
  163.                    (vlax-invoke adostream (quote close))
  164.  ;_ Close -- Close any open objects and related objects.
  165.  ;_             Use the Close method to close the Connection, Record, Recordset or Stream object to release any system resources
  166.  ;_             associated with it. Close object does not remove it from memory; then you can change its property settings and
  167.  ;_             turn it on again. Completely remove an object from memory, please set object variable to Nothing (Visual Basic)
  168.  ;_             or nil (Visual Lisp)  after close object .
  169.                    ret))))
  170.       (vlax-release-object adostream) ;_release object
  171.       (if (not (vl-catch-all-error-p ret)) ;_catch error
  172.         (if str
  173.           ret ;_by ReadText
  174.           (if (not (vl-catch-all-error-p
  175.                      (setq
  176.                        ret (vl-catch-all-apply
  177.                              (function
  178.                                (lambda nil
  179.                                  (vlax-safearray->list
  180.                                    (vlax-variant-value ret))))));_transform array format .
  181.                      ));_catch error of Null SQL Variant .
  182.             ret
  183.             (prompt (strcat "\n" (vl-catch-all-error-message ret))))
  184.           ) ;_returns
  185.         (prompt (strcat "\n" (vl-catch-all-error-message ret))) ;_princ error message
  186.         );_if , end result deal
  187.       );_progn
  188.     );_if
  189.   );_defun
  190.  

iautolisp

  • Mosquito
  • Posts: 9
Re: About read and write binary file
« Reply #8 on: September 26, 2023, 02:19:20 AM »
here is a routine for reading binary file to a txt file,and writing  a binary file from a txt file.

the question is :
1) why  I get different result in R2006 and R2011, it can't work in R2011,because in  "ReadBinary function"

The return value from  (vlax-safearray->list (vlax-variant-value arr))   is different. eg.
in R2006,it would be: (255 216 ........)      ----->it's what I need
in R2011,it would be: (-22785 -22824 ........)   ----->I don't know why  these numbers are larger than 255 or they are negative numbers?

2) On the (vlax-safearray->list (vlax-variant-value arr)) step, if I read a large size file, it will take a pretty long time.can I get some faster way?

Code: [Select]
(defun c:test ()
  (defun ReadBinary (FileName / stream arr)
    (setq stream (vlax-create-object "ADODB.Stream"))
    (vlax-put stream 'type 1) ;adTypeBinary
    (vlax-invoke stream 'open) ;adModeRead  =1 adModeWrite  =2 adModeReadWrite =3
    (vlax-invoke stream 'LoadFromFile filename)
    (setq Arr (vlax-invoke-method stream 'read (vlax-get stream 'SIZE)));read stream
    (vlax-invoke stream 'close)
    (vlax-release-object stream)
    (vlax-safearray->list (vlax-variant-value arr)) ;if a large size file ,it will take a long time in this step
  )
  (defun WriteBinary (FileName Array / stream)
    (setq stream (vlax-create-object "ADODB.Stream"))
    (vlax-put stream 'type 1) ;adTypeBinary
    (vlax-invoke stream 'open) ;adModeRead  =1 adModeWrite  =2 adModeReadWrite =3
    (vlax-invoke-method stream 'Write array) ;write stream
    (vlax-invoke stream 'saveToFile fileName 2) ;save
    (vlax-invoke stream 'close)
    (vlax-release-object stream)
  )

  (setq path (getfiled "Please select a binary file:" "c:/" "" 8))      ;get file path
  (setq f (open "C:\\test.txt" "W"))
  (setq data (readBinary path))
  (princ data f)
  (close F)

  ;;(setq aaa (vl-get-resource "test"))                                ;we can wrap this text file into .vlx file
  (setq f (open "C:\\test.txt" "R"))                                    ;open for read
  (setq l "")
  (while (setq s (read-line f))
    (setq l (strcat l s))
  )
  (setq array (read l))   
  (close f)                         
 
  (setq dat (vlax-make-safearray 17 (cons 0 (1- (length array)))))      ;17 for unsigned char
  (vlax-safearray-fill dat array)
  (setq bin (vlax-make-variant dat))
  (writeBinary "C:\\test.jpg" bin) ;write binary file.
)

Hello, I have a question, (setq dat (vlax-make-safearray 17 (cons 0 (1- (length array))))) When I use this code, I get an error; Error: LISP value of this type Cannot cast to VARIANT: -32257. I checked the CAD help documentation,

The type of safearray. Specify one of the following constants:

vlax-vbInteger (2) Integer

vlax-vbLong (3) Long integer

vlax-vbSingle (4) Single-precision floating-point number

vlax-vbDouble (5) Double-precision floating-point number

vlax-vbString (8) String

vlax-vbObject (9) Object

vlax-vbBoolean (11) Boolean

vlax-vbVariant (12) Variant
The integer shown in parentheses indicates the value to which the constant evaluates. It is recommended that you specify the constant in your argument, not the integer value, in case the value changes in later releases of AutoCAD.
Therefore, the reason for the error is (setq dat (vlax-make-safearray 17 (cons 0 (1- (length array))))) where 17 can only be a constant.
However, the constant corresponding to 17 was not found.
I checked on other websites that the constant corresponding to 17 is vlax-vbByte, but vlax-vbByte is invalid in autolisp.
How did you solve this?
CAD2012 is the version I am currently using