当前位置:文档之家› osip源代码框架详解

osip源代码框架详解

osip源代码框架详解
osip源代码框架详解

Osip协议源代码框架详解

Revision History

目录

1符号及缩写 (4)

2整体描述 (4)

3OSIP包的源代码框架解析 (5)

3.1 OSIP的TRANSACTION的EVENT的产生 (5)

3.1.1 定时器事件的产生过程 (6)

3.1.2 报文触发的事件 (7)

3.2 OSIP 的TRANSACTION的EVENT处理流程 (7)

3.2.1 ICT的处理流程 (8)

3.2.2 IST的处理流程 (9)

3.2.3 NICT的处理流程 (9)

3.2.4 NIST的处理流程 (9)

3.3 O SIP报文的解析 (10)

3.3.1 sip协议报文的解析整理流程 (10)

3.3.2 Osip报文头的解析 (12)

3.3.3 uri的解析 (14)

3.3.4 添加一个新的协议header字段 (15)

3.4 OSIP的TRANSACTION的管理 (16)

3.5 OSIP中DIALOG的管理 (18)

4EXOSIP包的源代码框架解析 (19)

4.1 L IB库的初始化和销毁 (20)

4.2 L IB库的主处理线程 (23)

4.2.1 2xx应答的重发处理机制 (24)

4.2.2 Exosip_execute执行流程 (24)

4.2.2.1 Exosip_read_message的处理 (26)

4.2.2.2 eXosip_process_response_out_of_transaction的处理流程: (29)

4.2.3 eXosip_automatic_action处理流程 (29)

4.3 C ALL的处理 (30)

4.3.1 创建Call的第一个INVITE (30)

4.3.2 INVITE的ACK应答的创建和发送 (32)

4.3.3 dialog内的请求的创建和发送 (33)

4.3.4 Dialog内answer的创建和发送 (33)

4.4 R EGISTER的处理 (34)

4.4.1 向一个服务器第一次注册 (35)

4.4.2 调整一个注册的注册超时时间 (35)

4.4.3 发送一个register注册 (35)

Osip源代码框架详解

1符号及缩写

2整体描述

开源代码的osip协议栈分为两个源代码包,整个协议栈采用lib库的形式,在内部没有使用到任务,采取与TCP/IP协议栈一样的策略,所以在使用上需要上层管理任务直接调用lib库提供的接口。因为在Lib库内部没有使用到像定时器、发送队列等的任务,而同时需要使用到定时器,所以在lib库的内部采用轮训遍历的方式不停的检查是否有定时器超时,这在某种程度上会浪费CPU的允许时间。同时整个lib库实现了对call, notify等的管理,为了实现重入,在应用启用多线程的条件下,内部启用的信号量和锁的使用,在下面的分析中不涉及到信号量和锁机制。

Lib库按照sip协议栈的层次关系分为两个lib包,底层的osip lib包实现对单个请求、应答、ACK的处理,包括message的解析、拼装、内容set和get,单个请求形成的transaction 相关操作以及通信两端形成的一个dialog的操作。

Lib库上层的exosip lib在底层osip lib库的实现基础上,实现对sip协议整理逻辑上的管理。Exosip主要关注的是sip协议的业务流程,包括call的整体管理,notify的整体管理,publish的管理,register的管理,option的管理,refer的管理和subscription的管理,其中最主要的为call和register的管理,这两个为sip协议栈必须实现的部分,另几个功能为sip协议栈扩展部分。从这几个业务的管理流程出发,在业务的底层它们会使用到相似的一些功能,如注册的认证,发送message,接收message,每个请求和应答形成的transaction,多个

transaction组合而成的dialog。

在message的处理方面,可以分为两类,一类为发送的message,因为是主动发送,所以上层管理层知道是什么类型的message,lib库直接提供各类接口供使用。一类为接收到的message,因为不知道是哪种类型,所以需要根据解析出来的message的信息来进行处理,这部分的处理在udp.c文件中。

整个lib库的初始化在exOsip中介绍。

3Osip包的源代码框架解析

在osip源代码包中最主要的包括了message的相关操作,其中最重要的为message的解析,即从获取到的一个message中解析生成一个能够被代码直接处理的message数据结构-——osip_message_t。与message结构相关的操作包括根据message数据结构的信息安装sip 协议规范组装成一个message字符串;message结构的初始化和释放;message结构的拷贝操作;以及从message结构中获取各种已经解析的成员变量的值和设置各个成员变量的值。在message的解析部分,除了message的头之外,还包括了body的解析,涉及到sdp协议,包括对每个sdp字段的解析。

在osip源代码包中,设计了一个与同一个请求相关的所有message的集合——transaction,在发送或接收到一个新的请求的时候就会生成一个transaction,其中ACK和CANCEL请求是比较特殊的,对于非2xx应答的ACK和初始INVITE请求是属于同一个transaction的,而对于2xx的请求是属于单独的transaction的,所以其重传操作由UAC来控制,而不在INVITE的transaction内部进行控制。CANCEL的请求除了本身建立一个transaction外,根据协议它还会去匹配要CANCEL掉的请求的transaction,如果匹配成功会CANCEL掉相应的transaction。

在osip包中同样设计了dialog相关操作,包括dialog的建立,dialog信息的保存,dialog 的匹配及删除等操作。

其它方面,包括多线程中使用到的锁和信号量及信号,内部使用到的链表,用于事件的队列(需要先进先出策略),一些平台无关的封装,定时器以及常量等的定义。这部分比较简单,而且都是最底层函数,直接封装了系统调用层。

3.1 osip的transaction的event的产生

transaction的状态变化是由事件来驱动的,当transaction上有事件产生时,根据事件的类型和当前transaction的状态来处理该event。

Transaction上的事件分为两类:一为定时器事件,在设定的定时器超时时会产生相应的定时器事件;另一类为事件驱动事件,如发送一个请求、应答或接收到一个请求、应答,发送一个ACK和接收到一个ACK,即是由报文产生的事件。

3.1.1定时器事件的产生过程

ICT、IST、NICT和NIST的定时器的事件产生流程都一样,对于每一个transaction,其定时器是有顺序的,ICT流程中TIMEOUT_B的优先级最高,TIMEOUT_B定时器触发后,会触发kill transaction的操作。当transactionff队列中有未处理的事件时,不处理定时器,直接返回,所以在transactionff队列中总的事件的数量是不多的。

所有的定时器函数调用底层同一个定时器检查函数__osip_transaction_need_timer_x_event。该函数会先检查该定时器是否启动,判断条件为(timer->tv_sec == -1),如果启动,检查当前时间是否超过定时器中设定的时间,如果是,则产生新的定时器事件。

因为定时器没有一个单独的任务,所以是采样轮训的方式检查是否有新的定时器事件产生,而不是根据系统时钟中断进行检测,因此会比较占用系统资源。

定时器的启动和修改使用接口osip_gettimeofday和add_gettimeofday。只需要设定定时器的超时时间,即设定了一个新的定时器。取消一个定时器,只需要修改定时器的timer->tv_sev为-1。

3.1.2报文触发的事件

包括一个新的invite、response、ack的发送或接收,除了对非2xx的应答ack外,其他的请求和应答都会产生一个新的transaction,并且产生一个新的sipevent事件。

3.2 osip 的transaction的event处理流程

在sip协议栈中为了更快更好的处理transaction,根据协议栈的描述,划分为四种不同的transaction,分别为ICT、IST、NICT和NIST。四种不同的transaction会有不同的处理流程和状态转换表,以及使用到不同的定时器。

ICT、IST、NICT和NIST的状态转换采样注册函数处理方式,为便于管理和使用注册函数,源码中使用了四个全局变量管理四种不同类型transaction的转换表:ict_fsm、ist_fsm、nist_fsm和nist_fsm。

osip结构如下:

struct osip

{

void *application_context; /**< User defined Pointer */

/* list of transactions for ict, ist, nict, nist */

osip_list_t osip_ict_transactions; /**< list of ict transactions */

osip_list_t osip_ist_transactions; /**< list of ist transactions */

osip_list_t osip_nict_transactions; /**< list of nict transactions */

osip_list_t osip_nist_transactions; /**< list of nist transactions */

……

}

整体简单处理流程如下图:

图3-1:transaction的event处理流程

3.2.1ICT的处理流程

如上图,ICT事件处理时:

1)检查osip管理结构中的osip_ict_transactions链表,如果没有链表元素,直接

返回OSIP_SUCCESS

2)获取链表中元素个数,并保存transaction到临时局部数组

3)遍历所有transaction,osip_fifo_tryget顺序获取每个transaction中的事件,调

用osip_transaction_execute处理每个事件,直到所有transaction中的所有事件

被处理完毕,然后返回。

Osip_transacton_execute执行时,根据传入的参数osip_transaction_t * transaction中的transactionde 类型获取到状态转移表的全局管理变量ict_fsm,并且根据event的type和transaction的状态调用fsm_callmethod——在文件fsm_misc.c,是状态转移注册函数的总入口——查询找到event的处理函数,并调用处理函数进行event的处理。

ICT的相关event的注册处理函数在ict_fsm.c文件和ict.c文件。ICT使用到了3个定时器:

TIMEOUT_A、TIMEOUT_B和TIMEOUT_D。

在client端发送Invite而需要创建新的ICT的transaction时,TIMEOUT_B被启动,时长为64*DEFAULT_T1(DEFAULT_TI为500ms),TIMEOUT_B为整个transaction的生命周期时长,如果超过这个时间,transaction会被结束。如同传输层使用的是没有传输保证的UDP,则设置TIMEOUT_A,TIMEOUT_D的间隔时间为DEFAULT_T1和64* DEFAULT_T1。如果传输层使用的是面向连接的TCP及相关协议,则直接使用TCP内部的重传机制,不在SIP协议层提供传输的保护机制,所以不启动TIMEOUT_A和TIMEOUT_D。TIMEOUT_A管理Invite的传送,在Invite被发送时,启动定时器TIMEOUT_A,并且在超时时间内还没接收到response的时候,重发该Invite。TIMEOUT_D用于管理ACK,当接收到的response不是>=300时,client端发送ACK,当重复接收到该invite的response时,重发该ACK,确保server 端在kill tranction前能接收到ACK。

3.2.2IST的处理流程

同ICT的处理流程,处理osip中的osip_ist_transaction链表。IST的相关event的注册处理函数在ist_fsm.c文件和ist.c文件。

IST使用了定时器TIMEOUT_G、TIMEOUT_H和TIMEOUT_I。使用方式与ICTL类似,详细见协议栈说明。

3.2.3NICT的处理流程

同ICT的处理流程,处理osip中的osip_nict_transaction链表。NICT的相关event的注册处理函数在nict_fsm.c文件和nict.c文件。

NICT使用了定时器TIMEOUT_E、TIMEOUT_F和TIMEOUT_K。

3.2.4NIST的处理流程

同ICT的处理流程,处理osip中的osip_nist_transaction链表。NIST的相关event的注册处

理函数在nist_fsm.c文件和nist.c文件。

NIST使用了定时器TIMEOUT_J。

3.3 Osip报文的解析

3.3.1sip协议报文的解析整理流程

当接收到一个message的时候,需要解析该message,生成一个代码能够处理的数据结构,该结构定义为struct osip_message,该结构定义的一个message的全部相关信息,这些信息主要是供transaction和dialog及dialog的更上一层如call,notify等的使用。

对一个message的解析流程如下图所示:

在接收到一个message时,调用函数osip_message_parse进行message的解析。首先调用函数osip_util_replace_all_lws替换掉message中的连续出现的‘\r\n\t’、‘\r\t’、‘\n\t’、‘\r\n ’、‘\r ’、‘\n ’为空格,message是以‘\0’为结束标志的,message的headers和body之间的分界是以’\r\n\r\n’为标志的,替换只替换到’\r\n\r\n’为止,即只替换headers部分出现的\t、\r、\n。由于sip协议栈规定,每个headers都是起新行,而且新行的头一个字符不为空格或\t,所以两个header之间的\r\n不会被替换掉,替换的只是一个允许multi合并项的header的内部多个值之间的“\r\n\t”或“\r\n ”。

举例如下:有两个header,其中Subject只允许单个值出现,Route允许有多个值出现,而且允许分行,但是分行必须以空格或\t开头,而Subject和Route行必需顶格开始,前面是没有空格或\t的,osip_util_replace_all_lws函数将Route header value中的两行间的\r\n\t转化为空格,即在逻辑上就成为一行了。

Subject: Lunch

Route: ,

一个message由三部分组成,首先是message的startline部分,该行指明这是一个sip 的message,包括sip标志,请求或应答说明,状态值,然后以\r\n做为和headers的分隔符。该\r\n不会被osip_util_replace_all_lws替换为空格,如请求的INVITE sip:bob@https://www.doczj.com/doc/8c218625.html, SIP/2.0或应答的SIP/2.0 200 OK,在三个属性之间有且仅有一个空格。起始行的解析由__osip_message_startline_parse进行解析,解析得到message的类型,message 的sipversion以及message的status_code,当status_code为初始化值0时,该message为一个请求,否则为应答。请求的startline由__osip_message_startline_parsereq进行解析,得到请求的request_uri;应答的startline由__osip_message_startline_parseresp进行解析。Startline部分的解析是严格安装出现的三个属性的顺序进行解析的,并将解析结果保存在osip_message的结构成员变量中。

然后解析messge的headers部分,调用函数msg_headers_parse。说明见osip 的header报文头解析。

如果message中在headers之后不是结束符’\0’,则继续解析message的负载部分,调用函数msg_osip_body_parse进行解析。Message的body解析首先查询headers头解析中保存

的content——即body――的属性:content_type,如果content_type中的type不为multipart,即不支持多种mime方式的content,说明body中就一个编码方式,直接将整个body解析为一个内容;如果type为multitype,说明有多个编码方式的body组合在一起形成一个整体的body,则以”--”为分隔符解析body,将body分为多个mime编码方式的字符串,每个解析后的body内容保存在osip_message结构中的bodies结构成员中。

3.3.2Osip报文头的解析

在解析message的header的时候,因为前面的osip_util_replace_all_lws已经转化了单个header内部出现的\r、\n和\t为空格,所以每个header之间可以使用\r\n做为分隔符进行分隔。如果字符串开头start_of_header已经到达结束符”\0”,则全部header解析完毕,返回成功;调用__osip_find_next_crlf找到这个header的结束字符并保存在end_of_header中;如果start_of_header为\r或\n,则已经解析到\r\n\r\n即headers的结束字符串,则返回成功,并且保存start_of_header到body中,即body是从\r\n字符串开始解析的,所以在body解析时,需要跳过\r\n及之后的空格部分;根据header内部分隔符“:”,取出header的hname和hvalue,其中hvalue在某些hname的情况下是允许为空的,然后调用

osip_message_set_multiple_header来解析该header的hvalue字符串;解析成功后,置start_of_header为已经解析完的header的end_of_header,开始解析下一个header。

在osip_message_set_multiple_header中,将headers分为两类,一类如上面例子中的Subject,只允许一个值,则直接调用osip_message_set__header进行解析;一类如上面例子中的Router,允许多个值,根据sip协议,每个值之间以“,”进行分隔,所以需要查询整个hvalue字符串,根据”,”将hvalue分隔成多个值,每个值调用osip_message_set__header进行解析并保存解析结果到osip_message的数据成员变量中。因为hvalue允许使用引号将值引起来,所以需要特别处理“,”是否出现在引号内部的问题。只有在引号外部的“,”才是header值的分隔符,而内部的“,”只是一个header值的一部分。

osip源码中osip_message_set__header对于message headers的解析采用注册函数的方式实现,采用这种方式能够在后继版本很方便的进行新的header的添加,并且不会影响到整个源代码的框架流程。

Osip_parser_cfg.c文件中定义了header头解析所使用到的全局管理变量:static __osip_message_config_t pconfig[NUMBER_OF_HEADERS];

__osip_message_config_t的结构定义如下:

typedef struct ___osip_message_config_t

{

char *hname;

int (*setheader) (osip_message_t *, const char *);

int ignored_when_invalid;

}__osip_message_config_t;

hname为sip协议定义的头字段的字符串,这些字符串定义在osip_const.h文件中;函数指针setheader为该协议header的对应的解析函数;ignored_when_invalid为是否忽略该header解析错误的标志,该标志值为1时,在解析该协议header发送错误时,忽略该错误,除sip协议规定的几个必要header之外,其他头应该采用忽略方式。

为了更快的根据header的hname,找到对应的setheader解析函数,采用了hash表的查询方式,根据hname生成一个hash值,并且需要保证没有两个不同的hname对应到同一个hash值中,以提高查询的速度。调用__osip_message_is_known_header (hname)获取到在数组中的index, 调用__osip_message_call_method (my_index, sip, hvalue)解析协议header,并且解

析的结果保存在结构osip_message_t * dest,中。

每一个header都包含几个通用的操作:header字符串的解析函数,即上段讲到的osip_message_set_xxx解析函数;header解析后的结构的获取函数,osip_message_get_xxx函数;根据header解析后的结构生成字符串的函数:osip_xxx_str;header解析后的结构的copy 函数osip_xxx_clone;header解析后的结构的是否函数:osip_xxx_free;以及header解析结构的初始化函数:osip_xxx_init。

对每个header的几个相关操作最终目的是提供协议的整个header的整体操作,包括osip_message_init,osip_message_free,osip_message_clone和osip_message_parse。

3.3.3uri的解析

绝大部分的header的解析都是相识的,只有其中有参数的部分的header的解析会比较复杂,最主要的有from、to、contact等,因为除了本身就有参数之外,其值中的request_uri 本身也可以包含有参数,而这两种参数之间是有区别的。

Sip协议栈规定header的表示分为header’s name, header’s value和header’s parameter。其中name和value之间用“:”分隔,value与parameter之间用“;”分隔,parameter之间也使用“;”相分隔。

在结构定义中header的value根据具体header包含的信息进行结构变量的定义,而如果包含parameter则直接定义一个gen_params的链表,所有的parameter都保存在这个链表中。

如下面from的定义,包含有from的名称及一个url,及相关的parameter:

struct osip_from

{

char *displayname; /**< Display Name */

osip_uri_t *url; /**< url */

osip_list_t gen_params; /**< other From parameters */

};

对应parameter的解析直接调用__osip_generic_param_parseall,该函数解析header的单个hvalue字符串中包含的所有parameter,在函数内部会根据“;”将字符串划分为几个parameter,然后解析每个parameter,将解析结果保存在gen_params链表中。Parameter的格式为pname=pvalue类型,等号两边允许空格。

From、to、contact以及via中间都可能出现url。url的解析接口为osip_uri_parse,输入为url的字符串,解析的结构保存在结构osip_uri_t之中。url包含有三部分内容:url的基本信息,url的header头部分和url的参数部分。开始部分与header头部分用“?”进行分隔,header头之间用”&”进行分隔,header头部分与参数部分用”;”进行分隔,参数之间也使用“;”进行分隔。Header部分调用函数osip_uri_parse_headers进行解析,结果保存在osip_uri_t结构中的url_headers成员变量中;parameter部分调用函数osip_uri_parse_params进行解析,其结果保存在osip_uri_t的url_params成员变量中。

在from、to、contact等包含url的header中,如果url中包含parameter,则整个url必需使用“<”“>”括起来,以表示一个完整url部分。所以解析from等header时需要检查是否包含”<”字符。

3.3.4添加一个新的协议header字段

1)需要添加多个一个对该字段进行解析的文件,包含一个header常用到的几个基本通

用操作,如果该header有特殊的地方需要处理,需要增加相关的处理函数,文件名

一般定义为osip_xxx.c和osip_xxx.h

2)需要在parser_init中注册新的header的解析函数,需要修改static

__osip_message_config_t pconfig[NUMBER_OF_HEADERS]中的

NUMBER_OF_HEADERS宏值。

3)在osip_const.h中添加新的header的宏定义,osip的相关的常量宏定义都定义在该文

4)在osip_message.c文件额osip_message_init函数中添加对该header相关结构的初始

化操作。在osip_message_free函数中同样添加对该header的相关释放操作,在

osip_message_clone中添加对该header的clone相关操作。

5)在osip_message_to_str.c文件中的_osip_message_to_str函数中添加该header转化为

string的函数注册。

6)如果该header不允许重复多个出现,即不允许multiple header,则在

osip_message_parse.c文件的osip_message_set_multiple_header函数中添加对该

header的处理。

7)在osip_message.h的头文件中的osip_message结构中添加对该header字段的结构。

8)在osip_headers.h文件中添加新的header的头文件引用。

3.4 osip的transaction的管理

transaction的操作主要包括transaction的初始化、transaction的free、transaction的匹配、从transaction中获取信息和设置transaction信息。

根据sip协议描述一个transaction由5个必要部分组成:from、to、topvia、call-id和cseq,这5个部分一起识别某一个transaction,如果缺少任何一部分,该transaction就会设置失败。

所以对每个部分的设置都会有一个设置函数:__osip_transaction_set_topvia用于设置topvia,对于发送端topvia为自己的via,对于接收端topvia为将message转发到自己的最后一个sip-proxy服务器,__osip_transaction_set_from用于设置message的发送端,__osip_transaction_set_to用于设置message的接收端,__osip_transaction_set_call_id用于设置一个dialog的标识值,该值是随机生成的,算法保证很长一段时间内生成的cal_id是不相同的,__osip_transaction_set_cseq用于设置cseq值,该值在同一个dialog内部是一直保持增长的,即同一个dialog的后面的transaction的cseq会比前面的transaction的值大,按照sip 协议其初始值可以是随机数,代码实现中如果是非register请求,从1开始,如果是register 请求的dialog,从20开始。

Transaction的初始化发生在接收到一个新的请求或发送一个请求的时候,该请求以及经过解析成为一个可以直接使用请求信息的结构osip_message_t。其初始化具体过程如上面所述,在设置完那5个部分后,还需要初始化event的队列,以及根据osip_message_t的type 初始化使用到的定时器结构,如ICT的ict_context。其它部分的初始化在exosip源代码中实现,相关的如your_instance、in_socket、out_socket和record都是未了方便exosip中对transaction的管理而设置的。

Transaction中的event的相关操作在如前面所述。

在transaction的匹配中,根据RFC3261的最新sip协议的描述,由topvia的branch_id 是否相同来匹配,如果相同,就是同一个transaction的请求和应答及ACK,为兼容旧版本的transaction的匹配规则,同时支持根据call_id, cseq, from_tag, to_tag来匹配transaction。如下图,为便于管理的transaction,所有的transaction保持在osip_t结构的四条链表中,按照处理流程的不同分为发送出去的INVITE类型请求和应答、其它类型请求和应答,接收到的INVITE请求和应答、其它请求和应答。

struct osip

{

void *application_context; /**< User defined Pointer */

/* list of transactions for ict, ist, nict, nist */

osip_list_t osip_ict_transactions; /**< list of ict transactions */

osip_list_t osip_ist_transactions; /**< list of ist transactions */

osip_list_t osip_nict_transactions; /**< list of nict transactions */

osip_list_t osip_nist_transactions; /**< list of nist transactions */

……

#if defined(HAVE_DICT_DICT_H)

dict *osip_ict_hastable; /**< htable of ict transactions */

dict *osip_ist_hastable; /**< htable of ist transactions */

dict *osip_nict_hastable; /**< htable of nict transactions */

dict *osip_nist_hastable; /**< htable of nist transactions */

#endif

};

在transaction的匹配过程中,如果是发出的请求,因为本地的transaction都会分配一个不重复的transaction_id,所以只需要比配transaction_id即可;对于incoming的message,如果是request,则匹配branch_id或者为兼容前面版本进行transaction的比配,按照协议RFC3261的17-2-3节的方式进行匹配;如果incoming的message是response,则匹配branch_id 或根据RFC3261的17-1-3节的规则进行匹配。

3.5 osip中dialog的管理

dialog的相关的管理操作包括dialog的初始化建立过程,dialog的销毁free过程,以及dialog的匹配。此外dialog中保存了相关的路由信息和cseq信息。

Dialog结构如下,由call_id、local_tag和remote_tag唯一确定一个dialog:

struct osip_dialog

{

char *call_id; /**< Call-ID*/

char *local_tag; /**< local tag */

char *remote_tag; /**< remote tag */

osip_list_t route_set; /**< route set */

int local_cseq; /**< last local cseq */

int remote_cseq; /**< last remote cseq*/

osip_to_t *remote_uri; /**< remote_uri */

osip_from_t *local_uri; /**< local_uri */

osip_contact_t *remote_contact_uri; /**< remote contact_uri */

int secure; /**< use secure transport layer */

osip_dialog_type_t type; /**< type of dialog (CALLEE or CALLER) */

state_t state; /**< DIALOG_EARLY || DIALOG_CONFIRMED || DIALOG_CLOSED */ void *your_instance; /**< for application data reference */

};

在dialog的初始化时,需要根据是client端或server端来确定dialog结构中的call_id、local_tag和remote_tag的值。根据是client端或server端来确定dialog的type,并且设置dialog 的状态。当做为client端,并且是在接收到发出的request的response时,调用osip_dialog_init_as_uac进行初始化dialog;如果是接收到server端发送过来的request,则调用osip_dialog_init_as_uac_with_remote_request进行dialog的初始化。如果是server端,调用osip_dialog_init_as_uas进行初始化dialog。

在dialog的匹配时,当是client端时,调用osip_dialog_match_as_uac进行匹配。检查接收到的response和dialog中的call_id,to_tag和from_tag是否匹配,如果全部匹配,则匹配到了该dialog。为兼容前面的版本,在dialog的to或者接收到的message的to header没有tag的情况下,比较dialog和message的from_uri, to_uri。如果匹配,则同样匹配的dialog。

当是server端时,调用osip_dialog_match_as_uas进行匹配。其匹配方法与client端的匹配方法相同。

对from_tag和to_tag的匹配处理,在transaction的匹配过程中同样使用到。

4Exosip包的源代码框架解析

在exosip源代码包中包含了提供给上层管理软件调用的关于call、message、option、refer、register、subscription、publish和insubscription的API,这些API的实现都在ex开头的c文件中。

为这些接口进行服务的函数,包括和osip lib库进行通信的部分的实现在以j开头的源文件中如jcall.c,其中jrequest.c和jresponse.c实现了request和response的message的通用构造实现。

同时exosip实现了传输层的四种不同的传输方式供上层的sip协议栈进行选择,分别为extl_dtls.c、extl_tcp.c、extl_tls.c和extl_udp.c,它们以注册的方式在Lib库启动的时候注册到lib库的钩子中。

为了支持多线程间的通信,在两个线程间采用pipe的方式进行实现,如果没有使用多线程,这部分源代码在编译时会被屏蔽掉。

对接收到的message进行的逻辑处理在文件udp.c中,这部分是整个协议栈逻辑比较复杂的地方。需要根据sip协议栈的标识描述和代码实现框架进行整理的把握。

4.1 Lib库的初始化和销毁

整个sip 的lib库有一个总的管理结构struct exosip_t eXosip,该全局变量在lib库被使用之前需要初始化,初始化函数为exconf.c文件的eXosip_init函数。Exosip_t结构如下:struct eXosip_tt

{

struct eXtl_protocol *eXtl;

char transport[10];

char *user_agent;

eXosip_call_t *j_calls; /* my calls */

#ifndef MINISIZE

eXosip_subscribe_t *j_subscribes; /* my friends */

eXosip_notify_t *j_notifies; /* my susbscribers */

#endif

osip_list_t j_transactions;

eXosip_reg_t *j_reg; /* my registrations */

#ifndef MINISIZE

eXosip_pub_t *j_pub; /* my publications */

#endif

#ifdef OSIP_MT

void *j_cond;

void *j_mutexlock;

#endif

osip_t *j_osip;

int j_stop_ua;

#ifdef OSIP_MT

Labview 自动生成程序及应用程序

Labview 自动生成程序及应用程序 周青教主 2011.12.28

一自动生成程序的功能 (1) 二相关背景 (1) 三实际开发应注意以下几点: (1) 四相关函数介绍及具体范例 (2) 1.相关函数 (2) 2.具体范例 (3) 2.1 最简单的一段代码如图 3所示: (3) 2.2 在While循环里面添加Add函数 (4) 2.3在前面板放置RoundButton控件 (4) 2.4在前面板放置簇,并在簇里面放置数值控件 (4) 2.5生成一个显示随机数的波形图表程序,并自动运行 (5) 2.6 将E的程序添加自动整理框图功能 (5) 2.7 连线前面板控件与接线端 (5) 2.8 前面板接线端样式介绍 (5) 3.小结 (5) 五自动生成应用程序 (5) 六应用示例 (6) 1.自动生成一个时钟的应用程序并自动生成相应EXE (6) 2.注意 (6)

Labview 自动生成程序及应用程序一自动生成程序的功能 在使用Labview过程中,我们能接触到各种项目设置、生成向导。如:创建仪器驱动项目向导,创建Labview实时项目向导等。使用向导可以减少用户的学习曲线时间,并能快速、准确和动态的生成代码。Labview VI脚本(VI Scripting)有助于通过编程,生成、编辑并检测Labview代码,便于开发向导程序。 通过LabVIEW 脚本可以实现编程创建、修改并运行LabVIEW 代码。它包含多种新的VI 服务器类、属性和方法,有助创建、移动并连接对象(包括前面板、程序框图、和图标),有助编辑连线板,有助创建新型动态VI。 二相关背景 1.什么是VI Scripting? ●VI Scripting 是Labview中功能强大的特性之一,它允许用 户通过程序去创建或修改Labview程序 ●基于VI Server ●从Labview8.6开始提供给用户使用 2.为什么我们需要VI Scripting? ●制作向导——能通过简单的对话框自动生成代码,减少学 习曲线并且增加生产率 ●支持VI检查——能获取VI内容并检查 ●创建编译器——方便把其它G或C代码转化为G代码 3.用VI Scripting,我们能做什么? ●理论上,我们应该能做任何Labview编辑器能做的事情 ●事实上,你能做如下事情等: ?创建新的VI ?添加新的对象到前、后面板 ?修改前、后面板上的对象 ?将前面板控件和接线面板相关联 三实际开发应注意以下几点: 1)利用Labview VI脚本(VI Scripting)创建Labview向导程序, 此向导程序用于动态生成VI;

20个代码生成框架

20个代码生成框架 11.1 CodeSmith http: 官方论坛: http: 版权形式:30天试用 开源:否需要先注册确认后才能下载 1.2 MyGenerator MyGenerator是又一个国外很不错的代码生成工具,有人觉得比CodeSmith 简单、好用。 所有api可以在帮助菜单中找到。 http: 官方论坛: 版权形式: 免费 开源:否 1.3 NHibernate. http: 官方论坛: 版权形式:

免费 开源:否 1.4湛蓝.Net代码生成器 http: 官方论坛: http: 版权形式: 免费 开源:否 1.5动软.NET代码自动生成器 一款人气很旺的免费C#代码生成器 http: 官方论坛: 版权形式: 免费 开源:否 1.6 CodePlus 专为sql server c#语言设计的代码生成器,功能还是很强大http: 官方论坛:

版权形式: 需要少量的注册费用 开源:否下载地址很神秘 1.7 CodeMaker http: 官方论坛: 版权形式: 免费 开源:否 https://www.doczj.com/doc/8c218625.html,代码生成器 可以使用本工具生成https://www.doczj.com/doc/8c218625.html,和C#语言的代码,以及三层架构与ORM架构代码,并且使用的ORM持久化组件是开源的,您可以在本软件的安装目录下找到它 官方论坛: 版权形式: 免费 开源:否 1.9 BMW业务模型及代码生成器 一款人气很旺的免费C#代码生成器

官方论坛: 版权形式: 免费 开源:否 1.10飞鹰CoolCoder 专门为采用nhibernate做关系对象影射架构的系统提供代码的工具,简单易用,虽然不提供源码,我们可以用反编译工具对其反编译看源码。这是个很不错的学习机会。 官方论坛: 版权形式: 免费 开源:否 1.11 AutoCoder自动代码生成器 AutoCoder自动代码生成器是一个根据模板自动生成代码的代码生成工具,根据模板的不同,可以生成任何语言(如: ASP、C#、C++BUILDER、DELPHI、JAV A、JSP、PHP、V B、https://www.doczj.com/doc/8c218625.html,……),不同层次结构(B/S、C/S、n-tiger……),基于不同数据库(ORACL E、MSSQL、MYSQL、

从simulink模型到PLC代码的自动生成功能

从simulink模型到PLC代码的自动生成是MATLAB2010提供的功能,目前支持的PLC编程工具有: CoDeSys2.3, CoDeSys3.3, RSLogix5000, B&R Automation Studio 3.0, PLCOpen XML, BeckhoffTwinCat 2.11以及Generic。 本文介绍了MATLAB生成TwinCat 2.11的ST文档的方法,并使用TwinCat 2.11建立相应的工程项目。 2. 使用MATLAB/simulink生成PLC的st语言功能函数的方法 MATLAB提供了很多demo一备参考,本文以MATLAB demo中的plcdemo_simple.mdl为例。首先在MATLAB命令行中执行命令demo,选择simulink PLC coder->Demos->Basic Introductions and Examples->Generating Structured Text for a Simple Simulink Subsystem,然后打开该模型。 打开参数配置面板(Simulation->Configuration Parameters),进入PLC Coder的选项页,将Targer IDE选为BeckhoffTwinCat 2.11。然后应用。 回到模型,右键点击SimpleSystem,选择PLC Coder->Generate Code For Subsystem。如果没有错误,将在当前目录下生成plcdemo_simple.exp文件及诊断对话框。该文件即为ST语言的PLC文档。如下

20个代码生成框架

20个代码生成框架 1 1.1 CodeSmith 一款人气很旺国外的基于模板的dotnet代码生成器 官方网站:http://https://www.doczj.com/doc/8c218625.html, 官方论坛:http://https://www.doczj.com/doc/8c218625.html,/default.aspx 版权形式:30天试用 开源:否 需要先注册确认后才能下载 1.2 MyGenerator MyGenerator是又一个国外很不错的代码生成工具,有人觉得比CodeSmith简单、好用。 所有api可以在帮助菜单中找到。 官方网站:http://https://www.doczj.com/doc/8c218625.html,/portal/default.aspx 官方论坛: 版权形式:免费 开源:否 1.3 NHibernate. NHibernate是Hibernate公司在Java自动生成领域取得巨大成功后推出的一款ORM工具. 官方网站:http://https://www.doczj.com/doc/8c218625.html,/ 官方论坛: 版权形式:免费 开源:否 1.4 湛蓝.Net代码生成器

一款基于软件自动生成理念,能直接生成应用的dotnet代码生成器 官方网站:http://https://www.doczj.com/doc/8c218625.html, 官方论坛:http://https://www.doczj.com/doc/8c218625.html,/ 版权形式:免费 开源:否 1.5 动软.NET代码自动生成器 一款人气很旺的免费C#代码生成器 官方网站:http://https://www.doczj.com/doc/8c218625.html, 官方论坛: 版权形式:免费 开源:否 1.6 CodePlus 专为sql server c#语言设计的代码生成器,功能还是很强大 官方网站:http://https://www.doczj.com/doc/8c218625.html, 官方论坛: 版权形式:需要少量的注册费用 开源:否 下载地址很神秘 1.7 CodeMaker asp,jsp,php代码生成工具,自动生成维护数据库信息的动态网页的代码生成器。它可以帮助ASP、JSP、PHP开发人员快速的开发简单的数据库维护程序。无需任何编码,只需将数据库结构导入到CodeMaker中并做简单的设置,CodeMaker即可生成完整的数据库操作页面。用CodeMaker可以简单快速的创建网站后台维护程序。提高开发效率数十倍以

程序代码自动生成系统的设计与实现

万方数据

万方数据

万方数据

万方数据

基于敏捷开发的高校网络评教系统 作者:吴衡, WU Heng 作者单位:天水师范学院物理与信息科学学院,甘肃天水,741001 刊名: 计算技术与自动化 英文刊名:Computing Technology and Automation 年,卷(期):2011,30(4) 被引用次数:1次 参考文献(8条) 1.丁增富;葛信勇构建教学质量监控体系努力提高教学质量[期刊论文]-高等农业教育 2004(03) 2.陈莉和谐校园构建于素质教育双效联动[期刊论文]-中国市场 2007(2-3) 3.成奋华;金敏基于敏捷过程的IT项目范围管理的研究与应用[期刊论文]-计算机技术与发展 2010(10) 4.徐诚斌;王金平MVC在ThinkPHP框架中的应用研究 2011(03) 5.赵国栋;黄永中开源软件在高校的应用与推广策略研究[期刊论文]-中国资源综合利用 2007(01) 6.马文龙;高宝成用php实现基于MVC模式的Web应用程序开发 2008(07) 7.原晓林基于B/S教学管理系统的开发与研究[期刊论文]-山西警官高等专科学校学报 2009(04) 8.蓝蔚青;曹剑敏;张帆高校学生网络评教系统的构建与完善[期刊论文]-高等农业教育 2006(06) 引证文献(1条) 1.蒋建洪电子商务系统协同开发实践教学研究[期刊论文]-中国教育信息化·基础教育 2013(5) 本文链接:https://www.doczj.com/doc/8c218625.html,/Periodical_jsjsyzdh201104028.aspx

【CN109765836A】PLC程序的自动生成方法、装置和实现装置【专利】

(19)中华人民共和国国家知识产权局 (12)发明专利申请 (10)申请公布号 (43)申请公布日 (21)申请号 201910108238.9 (22)申请日 2019.02.02 (71)申请人 宁波吉利汽车研究开发有限公司 地址 315000 浙江省宁波市杭州湾新区滨 海二路818号 申请人 吉利汽车研究院(宁波)有限公司 (72)发明人 胡峥楠 张尧 李志光 李红  黄天聪 李绪超  (74)专利代理机构 北京超凡志成知识产权代理 事务所(普通合伙) 11371 代理人 张阳 (51)Int.Cl. G05B 19/05(2006.01) (54)发明名称 PLC程序的自动生成方法、装置和实现装置 (57)摘要 本发明提供了一种PLC程序的自动生成方 法、装置和实现装置,其中,该方法包括:获取PLC 模板程序;该PLC模板程序包括硬件组态、变量名 称、安全程序和普通程序;获取保存有当前PLC的 控制对象的表格文件;在表格文件中,通过预设 的安全区域和模式区域将控制对象进行设备划 分,每个控制对象保存在对应的表格坐标中;根 据PLC模板程序和表格文件,生成当前PLC对应的 PLC程序。本发明可以缩短PLC离线程序的编写时 间,保证PLC程序的一致性,从而降低了编程的错 误率、提高了工作效率, 降低了项目成本。权利要求书2页 说明书9页 附图9页CN 109765836 A 2019.05.17 C N 109765836 A

权 利 要 求 书1/2页CN 109765836 A 1.一种PLC程序的自动生成方法,其特征在于,所述方法包括: 获取PLC模板程序;所述PLC模板程序包括硬件组态、变量名称、安全程序和普通程序; 获取保存有当前PLC的控制对象的表格文件;所述表格文件中,通过预设的安全区域和模式区域将所述控制对象进行设备划分,每个所述控制对象保存在对应的表格坐标中; 根据所述PLC模板程序和所述表格文件,生成所述当前PLC对应的PLC程序。 2.根据权利要求1所述的方法,其特征在于,所述根据所述PLC模板程序和所述表格文件,生成所述当前PLC对应的PLC程序的步骤,包括: 根据所述表格文件中,每个所述控制对象保存的对应的表格坐标,从所述PLC模板程序中导出对应的程序块的XML文件; 根据所述表格文件,修改所述XML文件的变量名称; 将修改后的所述XML文件导入TIA Portal中,生成所述当前PLC对应的PLC程序。 3.根据权利要求2所述的方法,其特征在于,所述根据所述表格文件,修改所述XML文件的变量名称的步骤,包括: 从所述表格文件中读取需要修改的变量名称和目标名称; 查找所述XML文件中所述需要修改的变量名称; 将所述需要修改的变量名称替换为所述目标名称。 4.根据权利要求1所述的方法,其特征在于,所述方法还包括: 从所述表格文件中获得存储文件夹名称; 建立所述存储文件夹名称对应的文件夹; 将所述PLC程序保存在所述文件夹中。 5.根据权利要求1所述的方法,其特征在于,所述方法还包括: 接收用户输入的模式区域的数量、HMI的数量、带模式旋钮的操作盒的数量。 6.一种PLC程序的自动生成装置,其特征在于,所述装置包括: 模板程序获取模块,用于获取PLC模板程序;所述PLC模板程序包括硬件组态、变量名称、安全程序和普通程序; 表格文件获取模块,用于获取保存有当前PLC的控制对象的表格文件;所述表格文件中,通过预设的安全区域和模式区域将所述控制对象进行设备划分,每个所述控制对象保存在对应的表格坐标中; 程序生成模块,用于根据所述PLC模板程序和所述表格文件,生成所述当前PLC对应的PLC程序。 7.根据权利要求6所述的装置,其特征在于,所述程序生成模块,还用于: 根据所述表格文件中,每个所述控制对象保存的对应的表格坐标,从所述PLC模板程序中导出对应的程序块的XML文件; 根据所述表格文件,修改所述XML文件的变量名称; 将修改后的所述XML文件导入TIA Portal中,生成所述当前PLC对应的PLC程序。 8.根据权利要求7所述的装置,其特征在于,所述程序生成模块,还用于: 从所述表格文件中读取需要修改的变量名称和目标名称; 查找所述XML文件中所述需要修改的变量名称; 将所述需要修改的变量名称替换为所述目标名称。 2

代码自动生成系统

本钢ERP代码自动生成系统的开发 史洪波 (本钢信息自动化公司软件开发事业部) 摘要:本钢ERP系统维护的工作量大,大部分的页面功能类似。在新增业务需求的情况下,可以利用本系统自动修改和生成JSP、Java、XML、SQL、Properties类型的全部代码,生成的代码可以提供新增、修改、删除、导入、树、打印、查询等基本功能。本系统原理是利用各种页面风格的JSP、Java、XML、SQL等文件作为模板,利用配置参数替换掉文件中可变部分,从而形成多种页面风格通用的代码生成系统。本文总结了本钢ERP中常用的6种页面样式,并用Java语言实现了其代码的自动生成过程,只需书写好DAO文件并在系统中填写少许的配置信息,然后点击按钮即可完成代码的产生,节省时间,提高工作效率。 关键词:ERP Java 代码自动生成 Benxi Steel ERP automatic code generation system Shi Hongbo (Benxi Steel Information & Automation Co.Ltd Software Development Department) ABSTRACT:There are a great deal maintain work in Benxi Iron and Steel Co. Ltd. ERP system, most of the page features are similar. In the case of needing new business, the system can automatically generate and modify all of the codes in many types, such as JSP, Java, Xml, SQL, Properties. Codes provide new, modify, delete, import, tree, print, query, and other basic functions and pride many different page styles by replacing the parameter of file. There are 6 common page styles are summarized in the Benxi Iron and Steel Co. Ltd. ERP, and use java language to achieve the automatic code generation process, just to write the file of DAO in the system and a little configuration information, then click the button to complete the code, saved a lot of time and improved the work efficiency. KEY WORD: ERP Java automatic-code-generation 作者简介: 史洪波,男,出生于1974年7月28日,1998年7月毕业于华东冶金学院工业分析专业,同年到本钢技术中心从事钢铁检验工作。2006年3月调至本钢信息自动化公司软件开发事业部从事软件开发工作。Email:mynameshb@https://www.doczj.com/doc/8c218625.html, 1、引言 本钢ERP系统有着良好的开发规范,命名规则有规律可循,因此在新增业务需求的情况下非常适合用代码自动生成系统来减少开发过程中的工作量,减少了开发人员的Ctrl+C/Ctrl+V操作,节省时间,提高工作效率。本系统原理是利用各种页面风格的JSP、Java、XML、SQL等文件作为模板,利用配置参数替换掉文件中可变部分,从而形成多种页面风格通用的代码生成系统。本系统采用J2SE中的Awt和Swing技术来绘制整个系统的图形界面,使系统界面整洁美观,使用xml文件作为本系统的配置文件,并对XML文件设定了DTD的格式校验,保证XML的格式良好。在系统界面中输入少量的条件即可产生和修改JSP、Java、XML、SQL、Properites等类型的文件,并对已经存在的文件先备份成Bak文件,生成的代码可具有新增、修改、删除、查询、导入、树、打印等功能。由于XML具有便于阅读和理解,可扩展等优点,而DAO文件格式的不规范性,系统中还提供了DAO文件与XML格式的相互转换,转换中使用了XLST技术,简化了转

利用MATLABsimulink的自动代码生成工具开发PLC程序

1. 对于大型的、比较复杂的控制系统,手工编程不仅耗费人力,而且准确率较低。MATLAB/simulink是一种强大的模块化、图形化的编程工具,能够很方便的设计控制系统。MATLAB 2010a提供了从simulink模型到PLC代码的自动生成功能。目前支持的PLC编程工具有: CoDeSys2.3, CoDeSys3.3, RSLogix5000, B&R Automation Studio 3.0, PLCOpen XML, Beckhoff TwinCat 2.11以及Generic。 本文介绍了MATLAB生成TwinCat 2.11的ST文档的方法,并使用TwinCat 2.11建立相应的工程项目。 2. 使用MATLAB/simulink生成PLC的st语言功能函数的方法 MATLAB提供了很多demo一备参考,本文以MATLAB demo中的plcdemo_simple.mdl为例。首先在MATLAB命令行中执行命令demo,选择simulink PLC coder->Demos->Basic Introductions and Examples->Generating Structured Text for a Simple Simulink Subsystem,然后打开该模型。 打开参数配置面板(Simulation->Configuration Parameters),进入PLC Coder的选项页,将Targer IDE选为Beckhoff TwinCat 2.11。然后应用。 回到模型,右键点击SimpleSystem,选择PLC Coder->Generate Code For Subsystem。如果没有错误,将在当前目录下生成plcdemo_simple.exp文件及诊断对话框。该文件即为ST语言的PLC文档。如下

java自动生成代码

1.与数据库建立连接 在DBUtil中设置数据库相关的参数 Class.forName(driverName); conn = DriverManager.getConnection(url, user, password); 2.获得数据库中的所有表 Mapmaps = new HashMap(); PreparedStatement pstate = conn.prepareStatement("show table status"); ResultSet results = pstate.executeQuery(); while (results.next()) { String tableName = results.getString("NAME"); String comment = results.getString("COMMENT"); maps.put(tableName, comment); } 3.获得每个表中的信息

封装一个实体来存储表中的信息 PreparedStatement pstate = conn.prepareStatement("show full fields from " + tableName); ResultSet results = pstate.executeQuery(); List lists = new ArrayList(); while (results.next()) { Column column = new Column(); String field = results.getString("FIELD"); column.setFeildMapper(field); String fieldName = processField(field);

自动代码生成规则

自动代码生成 1.表存储过程 TableName规则为剔出” _ ,” - ”等特殊字符,首单词大写例如Sys_Log 转换后为SysLog 如果是FlowER 中,则命名规则为 usp_SystemName_TableName_Operation 否则命名规则为usp_SystemName _Operation 存储过程名称及其功能: 是否存在记录usp_SystemName _IsExist 添加一条记录usp_SystemName _Insert 更新一条记录usp_SystemName _Update 删除一条记录usp_SystemName _Delete 获取实体usp_SystemName _GetModel 获取一批记录usp_SystemName _GetList 2.Entity 私有属性定义时不赋予初始值 命名空间规则为:BenQ.Application.SystemName.Entity ClassName规则为TableName剔出” _ , ” - ”等特殊字符,首单词大写例如Sys_Log 转换后为SysLog 3.DataAccess

命名空间为:BenQ.Application.SystemName.DAL 函数及其功能: -- 是否存在记录public bool IsExist(PK), public IsExist(int RowID) -- 添加一条记录public Insert(BenQ.Application.SystemName.Entity objEntity) -- 更新一条记录public Update(BenQ.Application.SystemName.Entity objEntity) -- 删除一条记录public bool Delete(PK), public Delete(int RowID) -- 获取实体public Entity GetModel(PK), public Entity GetModel(int RowID), -- 获取一批记录public DataTable GetList (Parameters), public DataSet GetList (Parameters), 4.Business 命名空间为:BenQ.Application.SystemName.BL 函数及其功能: IsExist(int RowID) -- 添加一条记录bool bool bool bool -- 是否存在记录public bool IsExist(PK), public bool public bool

ASCET代码生成简易说明

ASCET 代码生成配置 ETAS/陈炯 对于所有特定芯片的项目都需要对相应的target 文件夹中的 *.ini , *.mk and *.xml 等文件进行配置,以满足代码生成的需要. ASCET 从模型生成代码, 在利用外部工具对代码进行编译链接生成可执行文件。参看下图。 所有特定芯片的代码生成过程是由以下三种类型的配置文件控制的: 1. codegen [_*].ini 文件控制核心的代码生成器。 2. target.ini 给用于OS 配置的项目编辑器提供特定的芯片信息。 3. memorySections.xml 定义了用于ASCET 实施编辑器中的内存类的名称,并将名称与特定芯片的编译指令映射起来。 ASCET 对代码进行编译是通过一系列的GNU makefile (后缀是 .mk )的文件进行控制的. ASCET 对代码的编译是在对项目编译的过程中进行的。 本文档所有内容摘自 v6.1 SE 手册,具体相关信息请查看手册。 C:\ETAS\ ETASManuals\ASCET V C:\ETAS\ETASManuals\ASCET V6.1\ASCET-SE Manual.pdf 1 codegen[_*].ini 文件 ASCET 使用3个文件来控制代码生成器: ? .\target\trg_\codegen.ini ? .\target\trg_\codegen_.ini ? .\target\trg_\codegen_ecco.ini 这几个文件一起控制以下的属性: ? 代码风格,例如变量名称 ? 代码生成,例如变量初始化,使用 #pragma 语句等 ? 整合操作系统,例如消息的选择,创建钩子函数,OIL 描述文件的产生 用户可以定义在代码生成过程中使用的这些 *.ini 文件,但一般不用修改这些文件。

C#自动代码生成器

C#自动代码生成器 自动生成数据表和实体类 namespace SQLApplicationAutoGeneratiTool { public partial class Form1 : Form { string[] strArray = { "int", "string", "decimal", "bool", "char", "object", "double", "float", "DateTime" }; String path = @"..\..\..\类文件\"; public Form1() { InitializeComponent(); } private void 新增文本框ToolStripMenuItem_Click(object sender, EventArgs e) { ShengChengKongJian(); } private void ShengChengKongJian() { ComboBox cobm = new ComboBox(); for (int i = 0; i < strArray.Count(); i++) { cobm.Items.Add(strArray[i]); } TextBox textbox = new TextBox(); this.flowLayoutPanel1.Controls.Add(cobm);

this.flowLayoutPanel2.Controls.Add(textbox); } StringBuilder stbd = null; List strbldList = new List(); private void button1_Click(object sender, EventArgs e) { if (comboBox1.Text.Trim() == "") { MessageBox.Show("类名不能为空"); return; } stbd = new StringBuilder("using System;"); strbldList.Add(stbd); stbd = new StringBuilder("using System.Collections.Generic;"); strbldList.Add(stbd); stbd = new StringBuilder("using System.Linq;"); strbldList.Add(stbd); stbd = new StringBuilder("using System.Text;"); strbldList.Add(stbd); stbd = new StringBuilder("using System.Data;"); strbldList.Add(stbd); stbd = new StringBuilder("using System.Data.SqlClient;"); strbldList.Add(stbd); stbd = new StringBuilder("using System.Windows.Forms;"); strbldList.Add(stbd); stbd = new StringBuilder("namespace HospitalInformationManagmentSystem"); strbldList.Add(stbd); stbd = new StringBuilder("{"); strbldList.Add(stbd); stbd = new StringBuilder(" /* 作者:大理大学软件教研室杜老师"); strbldList.Add(stbd); stbd = new StringBuilder(" * 日期:" + dateTimePicker1.Text.Trim()); strbldList.Add(stbd); stbd = new StringBuilder(" * 版权:大理大学"); strbldList.Add(stbd); stbd = new StringBuilder(" * 你可以免费使用或修改以下代码,但请保留版权信息,否则将追究相关责任"); strbldList.Add(stbd); stbd = new StringBuilder(" */"); strbldList.Add(stbd); stbd = new StringBuilder(" public class "); stbd.Append(comboBox1.Text.Trim()); strbldList.Add(stbd);

什么软件给定代码生成流程图

在日常工作中,我们经常会需要画流程图,一般来说,大家都会选择使用PPT或者Word文档进行常规的流程图制作,虽然用这些办公软件也可以解一时之急,但终归不够专业方便,还非常费时,那要怎么才能方便快捷的解决问题呢?此时我们需要一个专业的软件来直接制作,这样才可以省时又省力,既方便又美观,分分钟让老板对你刮目相看。 当你对那些简洁美观的流程图感到羡慕不已,是否好奇它们是怎样做出来的,是否想知道需要什么样的专业技能。今天,这一切将变得非常简单,你只需要点击几下鼠标就能制作出属于自己的可视化流程图。而且一切操作都异常简洁。

流程图的基本符号 首先,设计流程图的难点在于对业务逻辑的清晰把握。熟悉整个流程的方方面面。这要求设计者自己对任何活动、事件的流程设计,都要事先对该活动、事件本身进行深入分析,研究内在的属性和规律,在此基础上把握流程设计的环节和时序,做出流程的科学设计。研究内在属性与规律,这是流程设计应该考虑的基本因素。也是设计一个好的流程图的前提条件。

然后再根据事物内在属性和规律进行具体分析,将流程的全过程,按每个阶段的作用、功能的不同,分解为若干小环节,每一个环节都可以用一个进程来表示。在流程图中进程使用方框符号来表达。 既然是流程,每个环节就会有先后顺序,按照每个环节应该经历的时间顺序,将各环节依次排开,并用箭头线连接起来。箭头线在流程图中表示各环节、步骤在顺序中的进展。 对某环节,按需要可在方框中或方框外,作简要注释,也可不作注释。 经常判断是非常重要的,用来表示过程中的一项判定或一个分岔点,判定或分岔的说明写在菱形内,常以问题的形式出现。对该问题的回答决定了判定符号之外引出的路线,每条路线标上相应的回答。 选择好的流程图制作工具 亿图发布第一款支持快捷操作的流程图制作工具从而极大的降低了专业流程设计的门槛,让大多数人可以在很短的时间里绘制出专业的流程图。

Classworking工具箱源代码生成与字节码生成的结合.(DOC)

JiBX 1.0 采用类处理技术对类编译后生成的字节码进行了增强并且支持直接生成新类。字节码生成比工作在源代码级具有一些显著的优势,然而,有时它却在生成和调试应用程序时造成一些麻烦。即使不考虑方便的问题,一些开发者也是除了“源代码”之外什么也不信任。JiBx 2.0 的首席开发人员Dennis Sosnoski 要使JiBX 2.0 同时支持字节码生成技术和源代码生成技术。在这篇文章中,他讨论了源代码生成技术和字节码生成技术的不同之处并且对于如何协调二者给出了自己的看法。 类处理技术允许程序直接处理由Java? 源程序编译后生成的二进制类表示。我的 JiBX XML 数据绑定框架就是这样的一个例子,它采用类处理技术增强了 Java 类文件,给类文件添加了实现与 XML 文件相互转换的方法。直接处理二进制类具有许多优势,包括当源文件不可用时仍然可以对类进行修改。在大多数情况下,这种二进制方法都是非常有效的。 但是有时缺少源代码也有不利之处。例如:在调试过程中要使用源文件。Java 调试器是被设计为工作在源代码级,如果没有与字节码指令相匹配的 Java 源代码,调试器实际上是无用的。如果使用基于类处理技术的框架产生错误,在追踪这些错误时,缺少源文件就成问题了。而 JiBX 并不从类文件中删除调试信息——这样您仍然可以照常调试原始代码——但是不能通过添加的与 XML 相互转换的方法进行调试。除了调试的实用性问题外,很多开发者并不愿意信任一个框架在字节码级上处理他们的程序,并且他们自己不能方便地检查处理结果也让他们不舒服。 我为 JiBX 2.0 开发定的目标之一就是增加用源代码增强代替字节码增强的选项。在这篇文章里,我将对照地介绍处理这两种类型代码的难点和我实现时所采用的技术。同时,我也会讨论字节码操作的一些细节,这是我以前的文章中没有涉及到的,特别是在调用方法和控制流领域。 源代码的替代品 通常,编译器把 Java 源代码翻译成字节码指令序列。因此,大多数类处理库完全忽视了源代码并且只工作在字节码级上。惟一的例外情况是 Javassist 库,它允许使用 Java 源代码的一种形式将字节码插入方法中或者构造新的方法(请参阅参考资料,找到我早期关于Javassist 的Java programming dynamics文章)。 JiBX 2.0 对于源代码/字节码提供双重支持的可能性,有可能建立在 Javaassist 的源代码处理方法上:不断地产生源代码,然后,当直接增强类文件时,Javaassist 将源代码转换成字节码。但是 Javassist 对于源代码的支持是有限的,并且包含一些与标准 Java 源代码不同的特性(包括方法变量的引用方式)。其次,Javassist 比一些其他的字节码库(特别是 ASM 库,参看在文章“ Classworking toolkit: ASM Classworking” 中的讨论)速度慢。我认为字节码增强仍然是 JiBX 2.0 的主要目标,在某些情况下(如使用 JiBX 联合一种 IDE 自动汇编),可能需要重复进行字节码增强,所以速度也是至关重要的。最后,javassist CPL 证书与 JiBX 的 BSD 证书并不兼容。鉴于上述原因,我决定采用另外一种方法。 我计划使用一个策略原型代替代码生成的实现,这时,根据使用源代码策略或者字节码策略的不同,同类型的操作将做不同的翻译。字节码生成与 JiBX 1.X 的实现基本上是相同的(通过使用 ASM 库而不是 BCEL 库)。源代码生成是新功能,并且它的结构形式必须考虑到在操作层面上与字节码生成的兼容性。

基于模型设计—自动代码生成之硬件驱动

声明:本文是《基于模型设计—自定义目标系统配置指南》的续集,主要和大家分享RTW工具箱做自动代码生成时,硬件驱动的编写方法;本文涉及两方面的技术难点CMEX S函数和TLC文件的编写,对这两方面不熟悉的童鞋可以先看看相关的Help 文档。 通过硬件驱动模块和上层控制模块的结合,可以实现嵌入式系统C代码的一键式生成,所生成的代码无需做任何修改就可以直接下载到单片机中。 本教程开发环境如下:Matlab2010a+CodeWarrior V6.3+Mc9s08dz60 欢迎汽车电子工程师加入QQ群:89462451,讨论Matlab在汽车行业的应用,分享自己的独门经验。 中断、IO、ADC、TPM、CAN、CCP、MCG……下一个模块硬件驱动,你也可以~~~ tntuyh@https://www.doczj.com/doc/8c218625.html, Godman2011.8.20 附件列表: dz60——该文件夹为自定义目标系统文件 系统TLC文件、主函数TLC文件、_file_processTLC文件、_callback_handler 文件、_make_rtw_hook文件、模块TLC文件(及C-Mex S函数) blocks——该文件夹为中断模块+数字输出模块的硬件驱动、 interrupt_init.c—中断模块C MEX S函数 interrupt_init.tlc—对应的TLC文件 dz60_dio_out.c—数字输出模块C MEX S函数 dz60_dio_out.tlc—对应的TLC文件 demos——该文件夹为测试用demo文件 interrupt_demo.mdl—测试模型,实现500ms和100ms任务 (33) 基于模型设计—自动代码生成之硬件驱动........................................................... 1、自定义目标创建 (3) 2、软件整体架构 (3) 3、硬件驱动编写 (5) 3.1主函数文件硬件驱动 (5) 3.2中断模块硬件驱动 (5) 3.3数字输出模块硬件驱动 (9)

中间代码生成

计算机科学与工程学院 课程设计报告 题目全称:常用边缘算法的实现 学生学号: 2506203010 姓名:王嘉 指导老师:职称: 指导老师评语: 签字:课程设计成绩:

编译器中间代码生成的研究与实现 作者:王嘉学号:2506203010指导老师:吴洪 摘要:在编译器的翻译流水线中,中间代码生成是处于核心地位的关键步骤。它的实现基于语法分析器的框架,并为目标机器代码的实现提供依据。虽然在理论上没有中间代码生成器的编译器也可以工作,但这将会带来编译器的高复杂度,低稳定性和难移植性。现代编译理论不仅要求中间代码的生成,还要求基于中间代码的优化。本文研究并实现了一个轻量级类C语言的中间代码生成器,并就中间代码生成的原理进行了细致的阐述。 关键字:中间代码生成、语法制导翻译、翻译模式、语法树、三地址码 一、目的及意义 在编译器的分析综合模型中,前端将源程序翻译成一种中间表示,后端根据这个中间表示生成目标代码。目标语言的细节要尽可能限制在后端。尽管源程序可以直接翻译成目标语言,但使用与机器无关的中间形式具有以下优点: 1.重置目标比较容易:不同机器上的编译器可以在已有前端的基础上附近一个适合这 台新机器的后端来生成。 2.可以在中间表示上应用与机器无关的代码优化器。 本文介绍如何使用语法制导方法,基于一种轻量级的类C语言FineC的词法分析器和语法分析器,一遍地将源程序翻译成中间形式的编程语言结构,如声明、赋值及控制流语句。为简单起见,我们假定源程序已经经过一遍扫描,生成了相应的词法记号流和符号表、词素表结构。基于FineC语法标准的语法分析器框架也已经能够正常工作。我们的任务就是补充这个框架,使其在语法分析的过程中生成相应的中间代码,并将必要的变量和函数声明存放在一个符号表链中。 二、目标语言词法和语法标准: 这里定义一个编程语言称作FineC(“fine”指代轻量、精妙)。它是一种适合编译器设计方案的语言。本质上是C语言的一个限制了数据类型、算术操作、控制结构和处理效率的轻量子集。 1.FineC语言的词法描述: [1]语言的关键字: else if return while int void

java 自动生成代码文档框架 idoc 项目模块说明

i-doc 项目简介 idoc是为 java 项目生成项目文档。 基于原生的 java 注释,尽可能的生成简介的文档。用户可以自定义自己的模板,生成自己需要的文档。 特性 ?基于 maven 项目生成包含大部分信息的元数据 ?默认支持 markdown 简化文档的生成,支持自定义模板 ?支持用户自定义文档生成器 ?支持用户自定生成文档的类过滤器 核心思想 数据 + 模板 = 视图 将文档元数据的获取和生成分离。 i-doc 希望达到的目标 对开发者的友好 手写文档的缺点自不用说。 以前也接触过类似 swagger-ui 等基于注解的文档生成工具,但使用起来终究不尽如人意。 基于注解的文档工具,让代码的可读性反而下降。 简洁性 java-doc 生成的文档又过于复杂。 实际使用中希望可以足够简介,比如不同系统之间的文档对接。 灵活性 作为工具,永远不知道使用者需要怎样的信息。 所以分成两大块。

元数据的生成,包含基本所有的文档信息。 文档的生成,提供默认的实现。用户可以基于模板灵活配置,也可以自行实现。 项目模块概览 idoc-api 定义用户使用的 api,提供最基础的接口和元数据。 便于用户在此基础上进行自定义开发,如指定生成文件的过滤方式。 idoc-common 当前项目的基础模块,提供基础的工具方法。 用户也可以引入此模块,进行自己的文档生成实现。 idoc-core 本插件的核心功能,主要负责将 java 文档的元数据信息整理出来,并提供核心的文档生成架构。 idoc-ftl 基于 Freemarker 模板的文档生成,支持其所有语法。 现在主要用于生成 markdown 文档。 用于可以自定义自己的模板,生成更适合自己的 markdown 文档。 idoc-poi 基于 Apache poi 生成 word、pdf 等类型的文档。 0.0.X版本暂时不引入,后续版本会实现。 idoc-test 测试模块。 一些使用案例可以参考这个模块,同时也为项目的质量提供一定的保证。

相关主题
文本预览
相关文档 最新文档