备案,今天查到的ARX中的Purge函数
未公开函数。
extern Acad::ErrorStatus purgeDatabase(AcDbDatabase *pDb);
extern Acad::ErrorStatus purgeObjectsFromDatabase(AcDbDatabase *Db,const AcDbObjectIdArray &Objs);
过年在家,无所事事,拾起从没耐心看的C#入门,用三天的时间系统的翻了一遍(除了web)。又在代码上试了一把,有些心得,留于此处,以作纪念。
在C#中,没有指针,这让c++启蒙的我很不习惯。仔细研读,在C++中,有值类型和引用类型,其中的引用类型,就近似于c++中的指针。不过是不声明为指针。
写到这里,忽然泛起疑问,在不是传参的情形下,值类型如何表示为指针。仔细思索,如果不是为了传参,值类型有必要使用指针么。
想到这里,思索一下,c++中指针的用途:地址,数组,以及函数指针。
数组和函数指针在c#中都有。其中函数指针在c#中表现为委托。剩下的,就只有地址了。而c++中,用到数据地址的地方,不计数组,就是传参了。传参有引用类型ref标识。c#委员会(不知道是不是这个机构)想的果然很是周到
。
c#中,有一种类型叫作可空类型,就是使值类型的值也可为null,这种类型的标识方式是int? ,很是神奇。而有了这种类型,原本在设计中的很多工作都轻松了。想必你也有这种时候吧,n个成员变量,每个成员变量都要配一个bool类型的变量以标识这个变量是否启用。这是非常痛苦的事儿。而在c#里,引进了可空变量,于是问题轻松了。此外,??操作符的引入,进一步简化了代码。你知道??操作符么?这是一个二元操作符,如果第一个操作数非空,那就使用第一个操作数,如果第一个操作数为空,那就采用第二个操作数。没搞好着色插件,随便写几行意思一下。
在C++中,我们要写
int n1,n2,n3,n4,n5……nx;
bool b1, b2, b3, b4, b5……bx;
而在c#中,
int? n1, n2,n3,n4,n5……nx;
而为了判断是否可用以给予默认值,
c++中:
set(b1 ? n1 : 0);
c#中:
set(n1 ?? 0);
c#中要求先赋初值后使用,增强了安全性。我们在c++中也是这样要求的,只不过在c#中,由人为要求变成了强制要求。
c#的界面开发。
听说c#的界面开发非常方便,研究后大失所谓。不知道是我手生还是理解有误。
创建界面,自动生成的代码中,混杂了大量的中文变量名。应不应该使用中文变量名的问题暂且抛开,就可读性而言,不可理喻。
需要一个控件一个控件的改name。当然了,这在vc中也是需要的,我们要在vc的设计界面一个一个的改ID,改属性。
在c#中的界面,不再是由资源完成。而是将界面与代码直接对应。这很神奇。所见即所得?html里[table][/table]于是真的有了一个table。
更神奇的是消息,不用消息映射了,直接把消息处理函数交给接收消息的控件。或许如果使用c#,我不需要在诸多控件的消息网中来回跟踪了。我喜欢c#中的消息。
linq 与数据库
linq,又一个很神奇的东东。可以到处查。干警出身吧。
查对象,查数据库,查xml。用法简单,语法简单,配合c#的类型推断和匿名类型,λ表达式,我只能说太帅了。
var CheckAllMyWant = from c in anyCollect
where c.anyKey == someValue
select new {Key = c.Key, Key1 = c.Key1, KeyN = c.KeyN};// 不要1~N之间了。。
foreach(var myWant in CheckAllMyWant)
{
Use(myWant.Key);
Use(myWant.Key1);
Use(myWant.KeyN);
// Use(myWant.Key2); 这将导致一个错误。
}
第一句查询又可写为
var CheckAllMyWant = anyCollect.where(c => c.anyKey == someValue).select(c => new{c.Key, c.Key1, c.KeyN});
数据库
研究了sql server的用法,怎么创建sql数据库,编辑,关系等等。因为以前都是用access,有些东西搞了半天才搞明白。标记一下。
在sql中,建立关系图后,要将关系图上的表相关联,需要用拖的。
找了半天,都没找见建立关系的命令菜单什么的,上网一查,原来一拖就好。
在sql中,要将一列设为自动编号,是用的标识规范这一项属性,而为了使这一项属性生效,又要先在表属性而设定标识列为需要设为自动编号的这一列。
为了找到在sql server里怎么创建数据库,在开始菜单里找了老半天,又到网上下了个什么sql server studio的,最后发现在vs里,从vs的服务器资源管理器里创建。
在c#里,当创建好了数据库,导入工程,就会自动生成对应的数据库封装代码,使得数据库操作变得异常简单。我又得说,这很神奇。
困了,就到这里。
c#以后如果会用到,或许会进一步研究,如果工作中不用到,那大概就研究到这里了,除非什么时候又有这个闲心。
写日志是为了复习,学而时习之,必有所得,孔夫子诚不欺我。
最后引用屈原的一句话,路漫漫其修远兮,吾将上下而求索。
2012年初,小y。
视频已全部看完。暂时不打算看两遍了。
目前对汇编已经有了一定的认识。也不打算再看一遍了。需要的时候再去查书就是了。也没打算用汇编来写程序。
刚开始的时候雄心勃勃,想要认真看视频,凭记忆写笔记,后来就完全时看视频时抄下来,再在第二天抄一遍到网上。一遍写到纸上,一遍输到电脑里,算是加深印象。
年后估计要把程序设计和算法过一下,但估计用的方式会是抄书,而不会再这样看视频了。
OVER
三、模块间的通信
(一) 伪指令PUBLIC和EXTRN
由于各模块被单独汇编,所以,如果模块甲要按符号名调用或访问其他模块中定义的某个过程或变量,那么模块甲必须告诉汇编程序此指定符号名(标识符)在别的模块内定义,否则在汇编程序甲时,汇编程序会给出符号未定义这类汇编出错信息。另一方面,如果在模块乙内定义的过程或变量准备供其他模块调用或访问,那么模块乙必须通知汇编程序,否则汇编程序不会把相应标识符保存到目标程序中,最终导致汇编失败。
伪指令EXTRN和PUBLIC就是分别用于通知汇编程序上述两种信息。
1. 伪指令PUBLIC
伪指令PUBLIC用于声明在当前模块内定义的某些标识符是公共标识符,即可供其他模块使用的标识符。
PUBLIC 标识符 [,标识符,…]
一个模块源程序内可使用多条PUBLIC语句,数据变量名及标号均可声明为公共标识符。
2. 伪指令EXTRN
伪指令EXTRN用于声明当前模块使用的哪些标识符在其他模块内定义。
它的一般格式如下:
EXTRN 标识符 : 类型 [, 标识符 : 类型, …]
上述语句中位于助词符EXTRN后的每一项标识符: 类型 声明一个在其他模块内定义的标识符
汇编程序为了产生合适的代码或保留恰当的存储单元,要求在声明标识符的同时指出其类型属性。标识符和类型之间用冒号分隔。
类型可以是NEAR, FAR, BYTE, WORD, DWORD等标识符类型属性。
注意: 把EXTRN伪指令安排在段的里面和段的外面是有区别的,如果EXTRN伪指令出现在某个段内,表示所声明的标识符虽在其他模块内,但却在同一个段内,如果EXTRN伪指令出现在段外,那么表示不知道所声明的标识符在哪一个段内被定义。
3. 声明一致性
各模块内PUBLIC和EXTRN语句必须互相响应,互相一致。凡是由PUBLIC语句声明的标识符,应该是其他模块EXTRN语句中用到的标识符。
(二) 模块间的转移
模块间的转移是指从一个模块的某个代码段转移到另一个模块的某个代码段。这种转移通常是以过程调用及返回的形式出现。例如模块甲调用定义在模块乙内的某个过程。但有时这种转移也直接采用转移指令的形式。
若两个模块的涉及转移的代码段在连接后不能组合为一个代码段,那么发生在这两个代码段之间的转移必须是段间转移,所以模块间的转移就成为远调用或远转移。否则模块间的转移可以是近调用或近转移。当然仍采用远调用或远转移也是完全可以的。
二、段的简化定义
新版汇编语言提供了段的简化定义方法,从而使程序员可以方便地定义段。
无论是编写独立的汇编语言程序还是编写供高级语言程序调用的函数,简化的段定义伪指令几乎总是使程序设计更容易。
本节介绍段的简化定义
(一) 存储类型说明伪指令
在程序员使用段简化定义伪指令之前,必须首先使用存储类型说明伪指令描述程序采用的存储类型。
存储类型说明伪指令的格式如下:
.MODEL 存储模型
常用的存储模型有:
(1) SMALL (小型模型)
全部数据限制在单个64KB段内,全部代码也限制在单个64KB段内,这是独立的汇编语言程序最常用的模型。在这种存储模型下,数据段寄存器可保持不变,所有转移均可变为是段间转移。
(2) MIDDLE (中型模型)
全部数据限制在单个64K段内,但代码可大于64KB,在这种存储模型下,数据段寄存器可保持不变,但会出现段间转移情形。
(3) COMPACT (紧凑模型)
全部代码限制在单个64KB段内,数据总量可大于64KB,但一个数组不能大于64KB
(4) LARGE (大型模型)
代码可超过64KB,数据也可以超过64KB,但一个数组不能大于64KB。
(5) HUGE (巨型模型)
代码可超过64KB,数据也可以超过64KB,并且一个数组也能大于64KB.
独立的汇编程序可选用任一种存储类型,对大多数完全用汇编语言编写的程序来说,小(SMALL)模型就足够了。
(二) 简化段定义伪指令
1. 简化的段定义伪指令
简化的段定义伪指令均以符号点引导。
常用的简化段定义伪:
(1)代码段简化定义伪指令
.CODE
例1:
写一个使系统喇叭发出嘟的一声的程序
.MODEL SMALL
.CODE
START: MOV DL, 7
MOV AH, 2
INT 21H
MOV AX, 4C00H
INT 21H
END START ; 结束代码段
伪指令.CODE说明代码段的开始,伪指令END说明段结束。
简化段定义伪指令说明一个段的开始,同时也表示上一个段的结束,伪指令END说明是一个段的结束。
(2) 定义堆栈段伪指令
.STACK [大小]
它表示一个堆栈段开始,若没有指令堆栈段的大小,则采用缺省值1024
(3) 定义数据段的伪指令
.DATA
例2:
如下伪指令定义了一个数据段
.DATA
VAR3 DB 5
LARRAY DW 50DUP( 0 )
MESS DB 'HELLO', 0DH, 0AH, '$'
例3:
增加一个大小为1024字节的堆栈段
.MODEL SMALL
.STACK 1024
.DATA
MESS DB 'HELLO' 0DH, 0AH, '$'
.CODE
START: MOV AX, DGROUP
MOV DS, AX
MOV DX, OFFSET MESS
MOV AH, 9
INT 21H
MOV AH, 4C00H
INT 21H
END START
在一个源程序模块中可定义多个由伪指令.DATA开始的数据段,如同在一个源程序模块中定义多个同名的数据段
(4) 定义远程(独立)数据段指令
定义独立数据段伪指令的一般格式如下:
它表示一个独立数据段的开始
.FARDATA [名字]
名字是可选项,如果使用,则设成该数据段的段名
例: 如下伪指令定义了一个独立数据段
.FARDATA
BUFF DB 1024(?)
此外,还有伪指令.DATA?和伪指令.CONST, .FARDATA?等。它们分别用于说明未初始化数据段的开始和常规数据的开始,未初始化的独立数据段,在编写纯粹的汇编语言程序时,一般不使用这些伪指令
2. 有关的预定义符
在上述程序片断中使用符号@CODE等是汇编程序提供的若干骑了定义符,它们类似于用伪指令EQU所定义的符号。
与简化的段定义伪指令相关的一些预定义符号有:
(1) 符号@CODE表示代码段的段名
(2) 符号@DATA表示DATA段和STACK段等集合而成的段组的组名
(3) 符号@FARDATA表示独立数据段的段名
第八章 模块化程序设计
本章要点:
1. 掌握段的完整定义及简化定义
2. 知道模块间的通信及子程序库
一、段的完整定义
(一) 完整的段定义
段名 SEGMENT [定位类型] [组合类型] [类别]
……
语句
……
段名 ENDS
通知汇编程序和连接程序如何建立和组合段
1. 段名
段名可以是唯一的,也可以与程序中其他的段名相同。在同一个模块中,如果已用相同的段名定义过段,那么当前这个段就被视为前一个同名段的继续,即同一个段。
对一个模块中的同名段而言, 后续同名段的定义伪指令SEGMENT中的可选项取值应该与前一个同名段相同,或者不再指定可选项的值而默认与前一个同名段相同
2. 定位类型
定位类型表示出当前段对起始地址的要求,从而指示连接程序如何衔接相连两段。
一般情况下,缺省的定位类型是PARA,即段起始地址于可用的第一个节(每节16个字节)的边界处
定位类型BYTE使得当前段紧接前一段,前后两段之间没有空间单元,所以是最节约的定位类型。
定位类型WORD使得段从偶地址开始,不仅较为节约,而且有利于数据单元定位在偶地址。
定位类型DWORD常用于8086的32位段。
一页等于256字节,所以定位类型PAGE可能导致最大的段间隔。
例1: 下程序的两个段定位类型均为PARA
DSEG SEGMENT PARA COMMON
MESS DB 'HELLO!', 0DH, 0AH, '$'
DSEG ENDS
CSEG SEGMENT PARA PUBLIC
ASSUME CS: CSEG, DS: DSEG
START: MOV AX, DSEG
MOV DS, AX
MOV DS, OFFSET MESS
MOV AH, 9
INT 21H
MOV AX, 4C00H
INT 21H
CSEG ENDS
END START
3. 组合类型
组合类型就是用于通知连接程序,如何把不同模块间段名相同的段组合在一起。
有如下组合类型:
(1) PUBLIC
表示当前段与其它模块中的组合类型为PUBLIC的同名段组合成一个段,组合的先后顺序取决于启动LINK程序时目标模块名排列的次序
(2) COMMON
表示当前段与其它模块中的同名段重叠,即起始地址相同,最终段的长度等于它们中最长的段的长度。
(3) STACK
组合类型STACK表示当前段是堆栈段,组合情况与PUBLIC相同
(4) MEMORY
组合类型MEMORY与PUBLIC相同
(5) AT表达式
表示当前段应该绝对地址定位,其地址即为表达式之值。LINK程序不对AT段生成任何代码或数据。
(6) PRIVATE
组合类型PRIVATE表示不与其它段组合,宏汇编程序MASM不识别此关键字。
若段定义伪指令SEGMENT语句中没有给出组合类型,就表示不与其它段组合。
例2:
某程序第一个源程序模块为例1, 第二个源程序模块如下所示:
DSEG SEGMENT PARA COMMON
DB 'OK'
DSEG ENDS
CSEG SEGMENT PARA PUBLIC
MOV AH, 4CH
INT 21H
CSEG ENDS
先把这两个源程序模块分别汇编,最后用LINK程序连接,命令如下:
LINK 例1 + 例2
模块2中的DSEG段与模块1中的DSEG段重叠, 模块2中的CSEG段和模块1中的CSEG段合并成一个段。
最后得到了可执行程序的内容如下:
0000: 0000 ; 两个段重叠后的结果为 'OKLLO..$'
0000: 0008 ; CSEG的类型类型是PARA导致的间隔
0001: 0000 ; MOV AX, 26H, 模块1中的CSEG段
4. 类别
类型用于表示段的分类。LINK程序总是使类型相同的段相邻,实际上只有类型相同的同名段才根据组合类型进行组合。
类别是一个由程序员指定的字符串,但必须使用单引号括起来。如果一个段没有给出类型,那么这个段的类别就为空。
例3:
设某个程序的模块甲如下:
; 模块甲(MODULE1)
DSEG SEGMENT PARA PUBLIC 'DATA'
…
DSEG ENDS
CSEG SEGMENT PARA PUBLIC 'CODE'
START:…
CSEG ENDS
END START
模块乙如下:
; 模块乙(MODULE2)
DSEG SEGMENT PARA PUBLIC 'XYZ'
…
DSEG ENDS
ASEG SEGMENT PARA PUBLIC 'CODE'
START: …
ASEG ENDS
END START
模块丙如下:
; 模块丙(MODULE3)
ESEG SEGMENT PARA PUBLIC 'DATA'
START: …
ESEG ENDS
END START
用以下命令把它们连接起来:
LINK MODULE1+MODULE2+MODULE3
在程序中各段的排列顺序如下:
模块甲的DSEG, 模块丙的ESEG, 模块甲的CSEG, 模块乙的ASEG, 模块乙的DSEG
(二) 完整的段定义(堆栈段说明)
一个完整的汇编程序一般应含有一个堆栈段,只有COM程序例外。
在程序的其它模块中也有组合类型为STACK的同名段,那么连接时将以连接的方式组合在一起,这样会构成一个存储空间更大的堆栈。
例4: 增加一个大小为1024字节的堆栈段
SSEG SEGMENT PARA STACK
DB 1024DUP(?)
SSEG ENDS
DSEG SEGMENT PARA COMMON
MESS DB 'HELLO', 0DB, 0AH, $
DSEG ENDS
CSEG SEGMENT PARA PUBLIC
…
CSEG ENDS
END START
LINK 程序会把组合类型为STACK的段的有关信息写入可执行文件中,设置的SS值是组合类型为STACK的段的段值。设置SP值是堆栈段的大小。
(三) 段组的说明和使用
例5: 下面的程序含有两个数据段和一个代码段
DSEG1 SEGMENT PUBLIC
VAR1 DB ?
DSEG1 ENDS
DSEG2 SEGMENT PUBLIC
VAR2 DB ?
DSEG2 ENDS
CSEG SEGMENT PARA PUBLIC
ASSUME CS: CSEG, DS: DSEG1
START: MOV AX, DSEG1
MOV DS, AX
MOV BL, VAR1
……
ASSUME DS: DSEG2
MOV AX, DSEG2
MOV DS, AX
MOV VAR2, BL
MOV AH, 4CH
INT 21H
CSEG ENDS
END START
另一种写法:
DSIS GROUP DSEG1, DSEG2
DSEG1 SEGMENT PUBLIC
VAR1 DB ?
DSEG1 ENDS
DSEG2 SEGMENT PUBLIC
VAR2 DB ?
DSEG2 ENDS
CSEG SEGMENT PARA PUBLIC
ASSUME CS: CSEG, DS: DSIS
START: MOV AX, DSIS
MOV DS, AX
MOV BL, VAR1
……
MOV VAR2, BL
MOV AH, 4CH
INT 21H
CSEG ENDS
END START