LISP调用DLL文件生成随机数
<p>这是用LISP调用DLL文件生成随机数的程序示例。</p><p>在VB6中创建一个ActiveX DLL工程,在其中将类模块修改为RND,将工程名修改为RNDAPP。在其中添加下面的代码:<br/>Public Function GetRND() As Double<br/> Dim i As Double<br/> i = RND<br/> GetRND = i<br/>End Function<br/>将其编译成DLL文件(“RND.dll”)。<br/>在WINDOWS下注册这个DLL文件。<br/>先将这个文件拷入C盘根目录下(注:也可放入相应文件夹下但文件夹名称中不能有空格)。<br/>再在运行中加入运行如下命令:Regsvr32 c:\RND.dll</p><p>然后编LISP程序。<br/>(defun c:testrnd( / rndobj rndnum)<br/> (setq rndobj (vlax-get-or-create-object "RNDAPP.RND"))<br/> (setq rndnum (vlax-invoke-method rndobj "GetRND"))<br/> (princ rndnum )<br/> (princ)<br/>)<br/>这里的rndnum就是相要的随机数。</p><p>这里是测试结果:<br/>命令: testrnd<br/>0.592458<br/>命令:<br/>命令: testrnd<br/>0.4687<br/>命令:<br/>命令: testrnd<br/>0.298165<br/>命令:<br/>命令: testrnd<br/>0.622697<br/>命令:<br/>命令: testrnd<br/>0.647821<br/>命令:<br/>命令: testrnd<br/>0.263793<br/>命令:<br/>命令: testrnd<br/>0.279342<br/>命令:<br/>命令: testrnd<br/>0.829802<br/>命令:<br/>命令: testrnd<br/>0.824602<br/>命令:<br/>命令: testrnd<br/>0.589163<br/>命令:<br/>命令: testrnd<br/>0.986093<br/>命令:<br/>命令: testrnd<br/>0.910964</p><p></p> 本帖最后由 作者 于 2007-1-23 0:05:14 编辑(defun C:TT2 (/ ETIME LST N STIME X)
(setq N 0
LST NIL
)
(repeat 10000
(setq LST (cons (setq N (1+ N)) LST))
)
(setq STIME (getvar "date"))
(setq LST (mapcar '(lambda (X) (nth X LST)) (rndsi (length lst))))
(setq ETIME (getvar "date"))
(prompt
(strcat
"\n程式共耗用時間: "
(rtos (* 86400.0 (- (- ETIME STIME) (fix (- ETIME STIME))))
2
3
)
"秒\n"
)
)
LST
)
程式共耗用時間: 0.469秒
程序也用了cputicks
rndsi和tt2已经打包,下载解压后调入cad可直接运行tt2
以前都能正常支行的,但现在提示这个了
命令: testrnd 出错: 参数类型错误: VLA-OBJECT nil
不知道是不是因为用的64位系统和64位CAD的原因。怎么解决呢?
好贴,我要试试64位软件能不能调用32位的DLL 顶!很好!学习 原创,大家下载研究吧。功能需大家自已开发。LISP和VBA都可用DLL文件扩展,呵……将一些LISP或VBA做不了的工作交给VB生成的DLL好了。 <p>这个方法不错,但却需要人工输入Regsvr32 c:\RND.dll,这点不好</p><p>我本来想在lisp前加上一句<font color="#ffa500">
</font><font color="#000000"> (STARTAPP "Regsvr32" "c:\\RND.dll"),但是会弹出“确定”按钮</font></p><p>不知道用vl-registry-write行不行?不过却不知道应该在注册表哪个位置?</p><p>望楼主指点</p> <p>自己解决了</p><p>在前面加上一句 (STARTAPP "Regsvr32" (strcat "/s \"" "c:\\RND.dll" "\""))就可以了</p> 好自已研究的会记的深刻。 <p>顶回去。</p> 本帖最后由 作者 于 2007-1-18 10:40:29 编辑
这个方法很不错,把lisp完成不了的函数交给VB来做!
但是对于这个随机函数只能生成0-1之间的值,最好能生某个范围内的随机数.
(defun rnd (rMin rMax / rndobj rndnum)
(setq rndobj (vlax-get-or-create-object "RNDAPP.RND"))
(setq rndnum (vlax-invoke-method rndobj "GetRND"));取得随机数
(if (and (= (type rmin) (type 1))(= (type rmax) (type 1)));如果是整数
(fix (+ rMin (* rndnum (- rMax rMin -1)))) ;则取整
(+ rMin (* rndnum (- rMax rMin))) ;对此范围内求值
)
)
稍微改了一下lisp函数。
下面是对无痕那个函数的修改,能自动判断整数和实数。
(defun rnd (rMin rMax / rndnum)
(vla-eval (vlax-get-acad-object) "ThisDrawing.setVariable \"USERR5\" ,CDbl((Rnd))")
(setq rndnum (getvar "userr5")) ;取得随机数
(if (and (= (type rmin) (type 1)) (= (type rmax) (type 1)));如果是整数
(fix (+ rMin (* rndnum (- rMax rMin -1)))) ;则取整
(+ rMin (* rndnum (- rMax rMin))) ;否则求此范围内随机值
)
)
本帖最后由 作者 于 2007-1-18 10:18:56 编辑
总感觉用DLL来生成一个随机数有些小题大作。
我来写一个,参考无痕的:
;生成随机数-by mccad:
(defun rnd(rMin rMax)
(vla-eval (vlax-get-acad-object) "Randomize : ThisDrawing.setVariable \"USERR5\" ,CDbl((Rnd))" )
(+ rMin(* (getvar "userr5")(- rMax rMin)))
) 这个方法原先是在xdcad的aeo那里看到的,不是我的原创.特此说明
by the way,在mccad的基础上:
(defun rnd(rMin rMax / e)
(vla-eval (vlax-get-acad-object) "Randomize : ThisDrawing.setVariable \"USERR5\" ,CDbl((Rnd))" )
(setq e (+ rMin (* (getvar "userr5")(- rMax rMin))) )
(if (= 'INT (type rmin)(type rmax))
(fix e)
e
)
);;测试:
(repeat 20 (print(rnd 3 7)))
(repeat 20 (print(rnd 3. 7)))