明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 8175|回复: 25

[【高飞鸟】] DynamicWrapperX更新说明及其高级实例

    [复制链接]
发表于 2016-5-15 15:47 | 显示全部楼层 |阅读模式
本帖最后由 highflybird 于 2021-1-4 12:41 编辑

DynamicWrapperX更新说明及其高级实例


DynamicWrapperX 已经有更新版本了。现在的版本比以前更好用。
这个版本的下载地址:
http://dynwrapx.script-coding.com/dwx/pages/dynwrapx.php?lang=en
注: 一些杀毒软件或者卫士管家之类的可能误报成病毒。
关于这个插件,下面的帖子我已经做了详细介绍。
http://bbs.mjtd.com/thread-85724-1-1.html
这篇帖子就作为《CAD的API编程指南(上)--DynamicWrapperX》的下篇吧。

现在看看它的一些新增加的东西:
1、 同时提供了32位和64位版本。可以两个都注册到系统,意味着如果你系统上装有32位的和64位的CAD,能同时使用此插件。如何注册请参考我上面的链接。另外关于对这个程序注册,本人使用可以直接在运行Regsve32,如要提供给他人用,需打包这个插件。下面附件为这个插件的安装注册程序。(不要运行源码)

2、 方法和函数的注册方式多提供了两种方法:
  a.Registration under a different name
  对API里面的函数,可以用不同的名字注册
  DWX.Register("user32:BadName", "GoodName", "r=n", "f=t");
  // BadName might be a function name that contains characters
  // not allowed in method names, or simply is too long.
  b.Registration by ordinal
  通过函数的地址注册。
  DWX.Register("user32:110", "MethodName", "i=p", "r=l");
  DWX.Register("user32:0x6E", "MethodName", "i=p", "r=l");
  其中标志参数 "f="是新增的,"f=t" 意味着函数以"thiscall"调用,"f=l"意味着立即调用GetLastError,获取LastError的错误代码。"t"标志只能用在32位DWX上,64位忽略此标志位。
3、 能够直接用汇编代码。
  例如:
  DWX = new ActiveXObject("DynamicWrapperX");
if (DWX.Bitness == 32)
{
    // The function multiplies its arguments and returns the result.
    Code = "8B442404F76C2408C3"
}
else
{
    Code = "4889C8 48F7EA C3" // mov rax,rcx; imul rdx; ret
}
CodeAddr = DWX.RegisterCode(Code, "Multiply", "i=ll", "r=l");
WScript.Echo(DWX.Multiply(5, 4));

用LISP这样写:
  1. (setq DWX (vlax-Create-Object "DynamicWrapperX"))
  2. (if  (= 32 (vlax-invoke DWX 'Bitness))
  3.   (setq code "8B442404F76C2408C3")
  4.   (setq code "4889C8 48F7EA C3")
  5. )
  6. (setq pCode (vlax-invoke DWX 'RegisterCode code "Multiply" "i=ll""r=l"))
  7. (setq ret   (vlax-invoke DWX 'Multiply 5 4))

这个功能很好,如果你够牛,在你的LISP中插入一段汇编代码,想必可为你的程序添加奇效。

4、 新增的函数和方法:
    ArrPtr (Array) 根据安全数组返回一个指针。这个方法对LISP语言无效。
    Bitness () 返回DynamicWrapperX的位数,32位或者64位。
    LastError([Flag]) 在调用API中如果出错,用此方法获得错误码。
    MemAlloc( Bytes [, ZeroMem] ) 这个很有用,用来分配内存。第一个参数为要分配的字节数,第二个参数如果设置为1,则内存用二进制0填充,可缺省。
    MemFree( MemPtr ),释放分配的内存。注意不要释放字符串内存。
    MemZero( Address, Bytes ),用二进制0填充内存。
    MemCopy( SrcAddr, DestAddr, Bytes ),内存拷贝。
    MemRead( Address, Bytes [, BytesPerGroup] [, GroupsPerLine] ),读取内存,返回十六进制字符串的形式。用法请参考帮助。
    MemWrite( HexStr, DestAddr [, Bytes] ),写内存。用十六进制字符串写数据到内存。
    ObjPtr( Object ) 从Object中获取此对象地址。
    ObjGet( ObjPtr ) 从地址中获取此地址的对象。
    VarPtr ( Variable ) 从VARIANT 中获取此变量地址。

    对于字符串指针的函数来说,Codepage是新增的。
    StrPtr( Var [, Type/Codepage] ),
    StrGet( Address [, Offset] [, Type/Codepage] )
    StrPut( String, Address [, Offset] [, Type/Codepage] )

    以下基本没变:
    NumGet( Address [, Offset] [, Type] ),从指针中获取数。
    NumPut( Var, Address [, Offset] [, Type] ),给指针赋值。
    Space( Count [, Char] )
    Version( [Field] )

5、 输入参数类型和返回值类型新增加了m,q,v三个类型,m,q这两个类型是用于64位上,v,指向VARIANT。另外作者提及到,如果对于LONGLONG之类的类型,可能不能用整数表达(LISP就这样,它已经超出了整数的范围),那么就可以用字符串表达。例如:
    DWX.Register("lib.dll", "func", "i=m")
    DWX.func("0xFFFFFFFFFFFFFFFF")
    DWX.func("-0x7FFFFFFFFFFFFFFF")
    DWX.func("18446744073709551615")
    DWX.func("-9223372036854775807")

6、 其他方面,请读者自行参考帮助文件。有不解之处可以联系作者本人。他是俄国人,懂英语,应该不懂中文。

下面我以两个实例说明对其操作。

实例一 :读写二进制文件,转化为文本文件。

在LISP编程中,编译成VLX文件时,只能打包进去文本文件和fas格式文件,例如LSP,DCL,TXT,fas,以及PRV文件,因此,如果想把其他的一些格式文件(譬如DWG格式)提供给用户的话,程序只好把这些二进制格式的文件转化为文本文件,放在资源里面。程序运行时,用vl-get-resource读取出来,再反转换为二进制文件。这之间的转换程序可用"ADODB.Stream"对象来实现。对于小文件来说,"ADODB.Stream"对象容易实现。32位CAD可用VBS脚本来实现大文件的操作,然而64位不能创建脚本对象(ScriptControl),大文件用"ADODB.Stream"操作非常费时。所以我在这里用DynamicWrapperX插件提供了二进制文件的转换程序。
因为它是基于汇编语言性质的,所以速度相当快捷,100M左右的文件用不了几秒钟就完成。当然,DynamicWrapperX插件本身要靠"ADODB.Stream"来实现打包的。另外提醒一句:不要利用这个去干坏事哦!否则我只能说:“怪我咯!”

下面是程序的核心代码:
  1. ;;;=============================================================
  2. ;;; 二进制文件转文本文件(对于小文件,譬如不超过100M)            
  3. ;;; 输入: DWX --DynamicWrapperX对象                             
  4. ;;;       In  --输入的文件名                                    
  5. ;;;       Out --要输出文件名,如为nil,则不输出文件,只返回数据值
  6. ;;; 输出: 返回二进制文件的十六进制数据字符串,为nil则读取失败。
  7. ;;;=============================================================
  8. (defun DWX:Bin2Txt (DWX In Out / File Size Buff pNum Data)
  9.   (setq File (vlax-invoke DWX 'CreateFileW In 1 1 0 3 128 0))   ; FILE_READ_DATA , OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL
  10.   (setq Size (vlax-invoke DWX 'GetFileSize File 0))             ; 此处也可用vl-file-size
  11.   (setq Buff (vlax-invoke DWX 'MemAlloc Size 1))                ; 一次性读到缓冲区
  12.   (setq pNum (vlax-invoke DWX 'MemAlloc 4 1))
  13.   (if (= (vlax-invoke DWX 'ReadFile File Buff Size pNum 0) 1)   ; 如果读取成功
  14.     (setq Size (vlax-invoke DWX 'NumGet pNum)                        ; 实际读取数据大小
  15.           Data (vlax-invoke DWX 'MemRead Buff Size)                ; 二进制数据
  16.     )         
  17.   )
  18.   (vlax-invoke DWX 'CloseHandle File)                                ; 关闭文件句柄
  19.   (vlax-invoke DWX 'MemFree Buff)                                ; 释放缓冲区内存
  20.   (vlax-invoke DWX 'MemFree pNum)                                ; 释放指向数据大小的指针
  21.   (if Out                                                        ; 如果需要输出到文件
  22.     (progn
  23.       (setq File (open Out "w"))
  24.       (princ Data File)                                         ; 把二进制数据输出到文本文件
  25.       (close File)
  26.     )
  27.   )
  28.   Data
  29. )

附件包含完整代码。

实例二 :简体繁体字的转换。

在平时工作中可能会接触到港台的文件,因为字符内码不同,一些东西显示为乱码,为了消除乱码,因此要转换。此程序能迅速转换字符文本对象,比用LISP表映射的方法快了不止一个数量级。除了简繁转换外,你稍加改造甚至就可以转换日文,韩文之类的。
  1. 核心代码:
  2. ;;;-------------------------------------------------------------
  3. ;;; For a locale specified by identifier,maps an input character
  4. ;;; string to another using a specified transformation, or      
  5. ;;; generates a sort key for the input string.                  
  6. ;;; 1024 -- LOCALE_USER_DEFAULT                                 
  7. ;;;-------------------------------------------------------------
  8. (defun DWX:LCMapString (DWX STR MapFlags / nlen pStr)
  9.   (setq nLen (vlax-invoke DWX 'LCMapStringW 1024 MapFlags str -1 0 0))
  10.   (setq pStr (vlax-invoke DWX 'memAlloc (1+ nLen) 1))
  11.   (setq nLen (vlax-invoke DWX 'LCMapStringW 1024 MapFlags str -1 pStr nLen))
  12.   (setq str  (vlax-invoke DWX 'StrGet pStr "w"))
  13.   (vlax-invoke DWX 'MemFree pStr)
  14.   str
  15. )

  16. ;;;-------------------------------------------------------------
  17. ;;; ANSI->Unicode  指定代码页转换为Unicode                     
  18. ;;;-------------------------------------------------------------
  19. (defun DWX:ANSI->Unicode (DWX STR Code / nLen pStr)
  20.   (setq nLen (vlax-invoke DWX 'MultiByteToWideChar Code 0 str -1 0 0))
  21.   (setq pStr (vlax-invoke DWX 'memAlloc (+ nLen nLen 2) 1))
  22.   (setq nLen (vlax-invoke DWX 'MultiByteToWideChar Code 0 str -1 pStr nLen))
  23.   (setq str  (vlax-invoke DWX 'StrGet pStr 0 "w"))
  24.   (vlax-invoke DWX 'MemFree pStr)
  25.   str
  26. )

  27. ;;;-------------------------------------------------------------
  28. ;;; Unicode->ANSI  Unicode转换为指定代码页                     
  29. ;;;-------------------------------------------------------------
  30. (defun DWX:Unicode->ANSI (DWX STR Code / nLen pStr)
  31.   (setq nLen (vlax-invoke DWX 'WideCharToMultiByte Code 0 str -1 0 0 0 0))
  32.   (setq pStr (vlax-invoke DWX 'memAlloc (1+ nLen) 1))
  33.   (setq nLen (vlax-invoke DWX 'WideCharToMultiByte Code 0 str -1 pStr nLen 0 0))
  34.   (setq str  (vlax-invoke DWX 'StrGet pStr 0 "s"))
  35.   (vlax-invoke DWX 'MemFree pStr)
  36.   str
  37. )


附件包含完整代码。

以后我会用这个插件继续提供更多,更强大的程序附后。

在这里,我强调两点,因为现在64位CAD比较流行了,LISP语言确还是基于32位的,因此,用这个插件需要注意指针内存分配大小、地址越界和数值溢出问题。



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x

本帖被以下淘专辑推荐:

发表于 2018-8-21 19:49 | 显示全部楼层
狂顶
用力顶
我用力顶
我很用力顶
再加上千斤顶
总之把它顶到顶
接着使出葵花宝顶
就算顶到史前也要顶
老子看了会用道德经顶
孔子亲自拜你为师天天顶
秦始皇站在阿房宫上使劲顶
汉高祖挥师杀向东罗马为你顶
吕布抛弃了貂禅而选择了帮你顶
张三丰见了后用太极拳九式全力顶
左冷禅召开武林盟主大会商讨如何顶
西门吹雪从此学会了最强一招剑神一顶
发表于 2020-12-26 15:39 | 显示全部楼层
学会了 改CAD标题    请赐教改下拉菜单名名称
发表于 2016-5-15 16:33 | 显示全部楼层
本帖最后由 springwillow 于 2016-5-15 17:12 编辑

好东啊,谢谢高版!顶顶顶
不过要想看懂这些东西还得学好C++,最好再能学点汇编知识。
发表于 2016-5-15 17:22 | 显示全部楼层
这已经超出了我等菜鸟的理解范围,看看就好支持一下
发表于 2016-5-15 18:49 | 显示全部楼层
完全看不懂,不知道这个东东能不能生成utf-8编码的xml文件
发表于 2016-5-15 21:16 | 显示全部楼层
曲高和寡
不过,DynamicWrapperX能出64位版,也是难得,我还以为作者再也不会更新了
高手到这种境界都是很寂寞的。。。
发表于 2016-5-16 09:09 | 显示全部楼层
望尘莫及!
发表于 2016-5-16 10:00 | 显示全部楼层
看帖学习。。。。。
发表于 2016-5-16 21:31 | 显示全部楼层
楼主高人 只能膜拜!多谢
发表于 2016-5-17 12:23 | 显示全部楼层
高大侠重出江湖,喜事!
发表于 2016-5-17 13:46 | 显示全部楼层
谢谢,高飞鸟,给出了 DynamicWrapperX 更新的好消息。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2022 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2022-5-18 15:21 , Processed in 0.304965 second(s), 28 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表