api应用

2024-09-08

api应用(精选8篇)

api应用 篇1

编制说明

一、任务来源

根据国家863计划信息技术领域,软件重大专项,中文Linux和办公软件相关标准与规范课题研究开发任务的规定,和根据国家质检总局和信息产业部2003年放国家标准和行业标准制、修订计划安排,制订《中文Linux应用编程界面(API)规范》。该项目由中软网络技术股份有限公司负责起草,项目计划代号为

二、工作过程

在国家任务下达后,中软网络技术股份有限公司就组织了工作组,在前期工作的基础上,收集与翻译了国际上有关Linux的主要标准的最新版本LSB 1.3(目前的最新版本为 LSB 2.0)和OpenI13N 1.3。总结了多年来在Linux开发工作和标准制订工作的经验。在“非典”肆虐期间,编写了制订《中文Linux应用编程界面(API)规范》的计划和大纲。

在“四所”的组织下成立了“中文Linux标准”工作组。在工作组的统一安排下,确定了编写工作的计划与大纲。于2003年9月初,编写了《中文Linux应用编程界面(API)规范》初稿,提交工作组讨论。工作组前后经过了近10次讨论,几经修改,先后提交了三次修改稿,才形成了《征求意见稿》。《征求意见稿》通过在网上和有关单位广泛征求意见,收集了许多很好的意见。工作组又组织了有FSG和OpenI18N有关人员和国内的Linux厂商、专家及有关人员参加的“Linux标准研讨会”。

2004年4月信息产业部成立Linux标准工作组,组织更大范围的企业参与标准的制定工作。在此基础上工作组对“意见汇众”进行了深入的整理、分析和讨论,确定了修改意见。根据这些意见,经过修改,我们提交了《中文Linux应用编程界面(API)规范》的《送审稿》。

2006年在发展基金及国家十五项目的支持下,中国电子技术标准化研究所组织国内主要Linux操作系统发布商,对标准的符合性测试展开研究,并根据测试研究的结果对标准做中描述不够严谨的地方做出相应调整。

三、主要说明

1、标准的目的Linux以其源代码的开放性已成为操作系统市场上的一支生力军,并成为促进我国信息化建设和发展的新生力量。“以Linux为契机,发展我国自主的操作系统和应用软件”已成为我国信息产业内的一个共识。Linux真正能够大规模地应用还面临着标准化、兼容性以及应用软件支持等诸多问题考验。坚决做好Linux的标准化和产业化工作,只有通过标准和规范来确保Linux各版本间的兼容和相对统一。要使Linux真正成为一个开放系统,必须吸收POSIX标准和国际Linux相关组织的研究成果,结合Linux的特点及中文信息处理的特殊性

对Linux操作系统中涉及中文信息处理的应用编程接口进行约定,以提高各Linux系统对中文应用程序的兼容性。该规范将使我国市场上基于Linux系统开发的中文应用程序具有源码级的可移植性,从根本上避免重复开发。

2、本标准制订的依据

1)多年来ISO/IEC和IEEE对开放系统的标准进行了大量的研究和制订工

作,已经形成了POSIX标准体系。各种开发厂商和组织也都声称以POSIX标准为依据进行开发。Linux也是按POSIX的规定进行开发的开放系统。这些都为本规范的制订打下了基础。

2)为了规范Linux发行版本,尽可能地实现各种Linux的兼容性,Linux

国际正在大力进行Linux Base Specification(LSB)的制订工作。已由2001年7月发布的LSB 1.0,发展到2003年初发布的LSB 1.3。而且,已经有若干重要的Linux版本提供商通过了LSB 1.3的符合性测试。2004年月正式发布了 LSB 2.0。LSB 2.0是一个重大事件,它比LSB 1.x系列有重大的发展、提高和变化。

3)为了使Linux能适用于各个国家和各种文字,Linux国际也在制订Linux

国际化标准。从LI18NUX 2000,到现在的OpenI18N 1.3。为各国语言文字在国际化的基础上实现本地化提供了依据。多年来我国中文信息处理技术有了巨大的发展。在各种系统上(包括Linux)在国际化的基础上实现中文信息处理的本地化,已经有了丰富的经验。而且我国已经制订了国标《开放系统中文界面规范》(于1996年制订,2003年修订)。这些都为本规范的制订打下了基础。

3、标准中的几个重要问题

1)关于LSB的遵循性问题。国际标准化组织在制订开放系统的标准时,首

先提出的是应用程序源码级的可移植性。POSIX标准也是以保证应用程序源码级的可移植性为目标进行制订的。源码级可移植性也是应用程序目标码级可移植性的基础。本规范的任务就是制订中文Linux应用编程界面(API)规范。目标是实现进行中文信息处理的Linux应用程序在遵

循本规范的Linux系统上的源码级的可移植性。但是,在制订的过程中发现,国际上许多重要的UNIX版本,都是声称遵循POSIX标准。而这些版本往往互不兼容,很难真正实现源码级的可移植性,更不要说实现目标码级的可移植性了。为了防止Linux走上UNIX版本不一致、不兼容,使用户很难使用的老路。Linux国际决定制订LSB,实现目标码级的可移植性。Linux国际这样做是有依据的。这是由于对于UNIX来说,先有UNIX的开发、后有标准。当标准制订时,已经有了各种UNIX的商业标准,虽然厂商宣称遵循POSIX标准,但为了厂商的利益,这些版本确实很难统一。而Linux是自由软件,而且核心的开发由Linus控制和发布。并且gcc等技术的发展也为实现目标码级的可移植性提供了可能。而且,LSB的符合性测试也日趋成熟。我们没有必要另搞源码级可移植性的符合性测试。经过反复讨论,工作组决定,整个中文Linux标准应遵循LSB 2.0。遵循本规范的实现应通过LSB 2.0的符合性测试。LSB 2.0 在制订过程中发现,针对不同的需要,LSB 除了分为LSB 规格说明的公共部分-gLSB和 LSB 规格说明的体系结构部分 – archLSB 两大部分外,就是 gLSB 也分为:LSB – generic 和 LSB – Graphics等。本规范虽然是API,但为了不割裂 LSB 文档,决定完整引用 LSB – generic 和 LSB – Graphics 这两部分。关于如何引用有几种不同意见,有在正文中引用 LSB 的主要内容、在正文中只提引用哪些内容,把LSB 2.0的译文放在附录中等等。我们也提供了几种版本。最后确定,只在正文中指出引用 LSB 2.0 的哪些内容。不在附录中放进 LSB 2.0 的参考译文(LSB 2.0 译稿初稿已完成)。

2)在制订国标《开放系统中文界面规范》时,当时的工作组曾邀请两岸三

地(大陆、香港和台湾)的有关中文信息处理的专家开了几次会。结果是在上述标准中规定了中文所需要而在别的标准中尚未提供的有关半角、全角转换、注音等6个函数。在制订本规范时考虑到《开放系统中文界面规范》中规定的字符界面和图形界面的有关函数在 LSB 2.0 中已包含,而这6个函数是独特的,故把它们包含在本规范中。但有的意见认为:这6个函数尚未在产品中实现,有的可以用别的 C 库函数替代。是否不需要了。在本送审稿中尚保留,请专家门审定。

3)关于输入方法服务器。中文输入方法是比较复杂的,可以说是各件语言

文件中最复杂的一种输入方法。而且中文输入方法又非常多。为方便与各种输入方法接口,能实现主流的中文输入方法,系统中必须提供输入方法服务器。输入方法服务器为应用程序编写者提供接口,这主要由协

议规定。由于中文输入方法复杂又有众多不同的输入方法,即使是最常用的也有若干种输入方法。为此,输入方法服务器也需要为输入方法编写者提供接口。使用此接口编写的输入方法都能挂接至系统上。目前,最流行的输入方法服务器是X window输入方法服务器(XIM)。但是,广泛使用的XIM协议也存在一些问题,最突出的是:首先,XIM是X Window系统的一部分,其结构也跟X Window紧密相连。故使用XIM的系统必须拥有X Window。而X Window系统规模厖大,不太适用于一些嵌入式系统。其次,它不支持多种语言。虽然,X Window能使用Unidode的UTF-8编码,也即整个GB18030的多民族语言文字库都可以使用。可是,输入法服务器不能通知客户端用户输入的是何种语言。此问题导致采用XIM协议,会阻碍应用软件支持多民族文字和多国语言。创造XIM协议的同一组人员,觉察到这些问题,设计出一套新的协议,称为互联网-企业内部网输入法协议-IIIM(Internet-Intranet Input Method Protocol)协议。此协议已有实现者,且有日益扩展的趋势。故在本规范中同时提供这两种协议。

4)中文输入方法很多,为了使主流的中文输入方法能用于或移植到遵循本

规范的Linux系统上来,本规范规定了中文输入方法与中文输入服务器的接口。

5)Linux上的支撑软件很多,特别是桌面系统。这些软件各有特色且都在发展。因而,Linux上的打印很复杂,很难统一。但为了使应用程序能正确打印出中文。本标准对系统配置的主要中文字库规定了规范名称,也规定了字库的存放目录。

四、验证情况

从2006年8月启动对相关Linux产品的规范符合性测试,主要目标是验证规范的合理性和测试方法的可行性。目前已经进行的本规范符合性测试产品包括:中标服务器操作系统3.0、红旗服务器操作系统5.0、中标桌面操作系统3.0、红旗桌面操作系统5.0,通过这些测试证明了规范要求全面、合理,符合性测试方法可行。

Linux标准工作组

api应用 篇2

自19世纪九十年代互联网出现以来, 地理信息系统的各个方面都经历了显著的转变, GIS的概念模式从一个孤立的体系转变成为一个互操作的体系, 从单机模式转变为到分布式的解决方案, 从个人所有的数据形式转变到开放的规范转换数据形式, 从桌面平台到互联网环境。本体论的改变和科技的进步增强了公众对GIS的发展潜力的认识, 同时也激励了科研人员去探索更强大的GIS技术。地图API指的是地图应用程序编程接口, 在2005年被提出, 它是一种可产生巨大网络应用的免费适用工具, 受到了许多网页开发者、地理学者甚至是非相关地理人员的称赞。

最新网络服务的发展, 如三维可视化工具 (Google Earth和World Wind) , 地图应用程序编程接口 (API) 有助于网络分布式GIS的实现和发展。在互联网技术中的最新成果和著作使得人们渐渐地意识到网络服务和三维可视化工具在GIS中的重要性, 2005年Smiatek将网络服务的实施描述成气候模型访问GIS数据库时的一个中间平台, 基于网络服务技术, 2005年Tait在开发分布式GIS应用时, 引入了入口和网关的概念来发现和发布地理目录。

Nourbakhsh和Pearce等人在06和07年就高度赞扬了三维可视化是一个非常有价值的工具, 特别是研究三维空间和开发全球最新的网络GIS应用方面, Lisle在2006年就给出了一系列使用谷歌地球可视化和开发许多地质平台的好例子。然而, 不像网络服务和三维可视化工具, 地图API并没有受到科学者们同等的关注, 尽管地图API受到了网络开发者的热捧, 但是很少有人指出地图API在网络GIS应用方面的巨大潜力。

本文研究了地图API在网络GIS开发应用方面的潜力。研究提出了一个概念模式用于去开发和扩展API现有空间功能, 如:浏览和处理矢量和栅格数据的功能等。特别的是, 谷歌API被采用去开发一个网络原型, 用于散布美国密歇根州芒迪小镇城市蔓延的空间信息, 该网络原型表明一个空间数据库的空间和属性信息有可能使用谷歌API通过地理标记语言得到高效地显示。通过使用谷歌API, 地理标记语言 (GML) 在开放性的网络GIS开发中表现出了巨大的潜力, 本项研究对于未来使用地图API开发网络GIS应用具有重大的意义。

2 方法论

为了去挖掘地图API在网络GIS应用方面的巨大潜力, 这篇文章提出了一个框架, 用于处理和可视化地理标记语言数据以及使用地图API的通用遥感影像。提出的概念模型由三步组成。

(1) 将GIS数据库转换为地理标记语言或者任何一种网络兼容的遥感影像;

(2) 通过解析地理标记语言或者下载网络兼容的遥感影像来查询空间数据;

(3) 将空间数据和相应可视化的地图API类进行叠加。图1描绘了概念模型的概览和相关的技术。基于需要利用本地网络服务器存储的空间数据, 提出的框架也需要通过地图API和一个外部网络地图服务器连接起来, 该外部地图服务器提供了分布式的GIS服务和辅助空间数据。

2.1 数据的转换

存储在GIS数据库中的空间数据首先被转换为地理标记语言, 地理标记语言是一种数据描述语言, 编码和整合地理特性, 如空间和属性信息。在GML 3.x编码规范中, 为了支持几何基元 (如点、线串和多边形) 、集合复合体 (如封闭的几何基元集合) 和几何聚集 (如多点、多线、多多边形、多几何等) , 之前版本的核心模块被扩展。因此地理标记语言能够用来编码复杂的数据模型和展现真实世界的几何体。通过使用网格地理标记语言和改正的网格标记语言元素, 地理标记语言就可以用于去编码遥感影像。

2.2 数据查询

当空间数据被转换为合适的格式后, 地理标记语言文件和网络兼容图像在网络浏览器上被下载为单独的数据图层。为了提高处理的速度和用户的交互能力, 本研究采用了一种异步Iava Script和XML的网络开发技术来解析和查询地理标记语言文件。该技术只支持和服务器之间小量信息的交换, 避免用户发出请求的时候, 重复下载整个页面造成停机状态。

一旦web服务器得到地理标记语言文件, 各个元素和标记就可能经由XML文档对象模型被查询。每个数据图层将会产生一个数组, 去存储来自XML数据的所有地理要素的空间几何和属性信息。基于这种方法可以实现一个属性查询, 利用X查询和X路径, 将一个具有特殊属性的小子集从整个数据库中提取出来。

2.3 数据的叠加

大多数地图API在地图目录中都具有一些叠加通用几何要素的空间功能, 然而并不是所有的地图API都含有能可视化多种数据模型和它们的几何体 (如点、线、面) 的内嵌类库。在某些情况下, 网络开发者需要去开发通用的类库或者使用第三方类库去叠加多种几何地物和数据模型。

本实验采用的是谷歌API, 它提供了多余点、线、多边形的支持。一旦单个图层的地理要素从地理标记数据中查询出来, 就立即存储到一个数组中, 通过使用相应的类库, 存储的空间信息和属性信息可能作为一个参数去创建地图目录中自定义的叠加图层。类似的可以使用地图API来将栅格图层叠加到地图上。

本实验采用的谷歌API来实现的, 然而概念模型可能还可以使用于其他的地图API中, 假设选择的地图API支持以上所述的技术。本研究开发了一个网络原型用于散布美国密歇根州芒迪小镇城市蔓延的空间信息。

3 结语

本研究提出了一个使用地图API来可视化、浏览地理信息的框架, 该地理信息包含了矢量和栅格数据。基于本研究产生了一个网络原型, 研究证明该原型能够在数据挖掘方面给用户提供高效的动态交互。开放性的地图API源代码、灵活性的规范数据标准展现了地图API在新互联网GIS应用开发中具有的巨大潜力。能够在未来GIS的发展中提供强大的推动力。

4 评论

本文主要研究地图API在网络GIS应用开发中的巨大潜力, 虽然地图API具有源代码开放性、全球数据覆盖性、动态导航性、可查询性和易实现性。但是现存的API缺乏地理信息系统的空间功能, 很少有人发觉地图API在网络GIS应用方面的巨大潜力。而本文指出了地图API在网络GIS应用方面的潜力, 通过使用谷歌地图API来开发了一个网络原型, 用于散布美国密歇根州芒迪小镇城市蔓延的空间信息。并且提出了一个概念模型框架来可视化和浏览矢量栅格数据等地理信息。基于本研究产生的网络原型, 研究证明该原型能够在数据挖掘方面给用户提供高效的动态交互。

地图API的开放性和易实现性, 使得人们现在越来越关注它和GIS的结合, 使得分布式GIS的应用成为可能, 为不同地区的人们提供网络GIS服务, 实现了GIS的全覆盖性。开放性的地图API源代码、灵活性的规范数据标准展现了地图API在新互联网GIS应用开发中具有巨大的潜力, 能够在未来分布式GIS的应用发展中提供强大的支持和推动力。目前研究中提出的框架还需要不断地试验验和改进, 不断地完善和进步, 使得地图API能够和GIS完美结合, 实现基于地图API的网络GIS服务, 实现分布式的互操作, 使得网络GIS的发展更进一步, 推动网络GIS服务, 为人们的生活和工作提供更为方便的服务, 为灾害预警提供更为精准的决策支持。

摘要:地图API的成功很大程度上在于它的开源性、全球数据覆盖性、动态导航性、可查询性和易实现性。尽管它具有在线地理数据动态浏览的多功能性, 但是相对于其他网络地图服务而言, 现存的API缺乏地理信息系统的空间功能。本文是为了评论地图API在网络GIS应用方面的潜力, 通过使用谷歌地图API来开发了一个网络原型, 用于散布美国密歇根州芒迪小镇城市蔓延的空间信息。实验表明了矢量和栅格数据都能很好的展现在地图API上。而且地理标记语言 (GML) 在开发开放性能的网络GIS时具有巨大的潜力。提出了几种具有潜力的解决性方案去扩大地图API中GIS操作范围, 如:合并有关的可扩展标记语言以及扩充Java Script的类库。

api应用 篇3

SolidWorks Composer是 SolidWorks整体解决方案中一款基于 3D CAD数据来创建清晰、有效的产品说明文档的软件,可以极大地丰富企业产品展示、说明的形式。 SolidWorks Composer具有优秀的交互式动画制作能力,可以呈现复杂的产品动态图形内容。

除此之外,SolidWorks Composer还可以将自身的文档数据与主流的静态文档格式相结合,比如 PPT、Word、PDF和 HTML页面等格式。在与这些文档结合后,使用者还可以依照自己的想法定制一些创新功能来实现更多精彩的产品说明形式,让传统文档焕发活力,这就需要依靠SolidWorks Composer的 API,本文即是对此展开介绍。

下面将以在Word中嵌入SolidWorks Composer的SMG数据为例进行说明。

二、将 SolidWorks Composer数据发布到文档中

Microsoft Office Word是日常工作中主流的文档处理工具,也常用来制作企业的产品说明书和应用说明手册。借由 SolidWorks Composer我们可以让 Word变成互动的交流工具,使得对于产品的展示更加生动和全面。

我们首先要准备一个已经制作完毕的 SolidWorks Composer数据文件,即 SMG文件,将这个文件发布到Word中。然后打开一个 Word文档,当然也可以是固定的模板,我们这里新建一个新 Word文件。然后在 Word中取得 SolidWorks Composer开发控件,基于 MicrosoftOffice Word 2003版和2007版本的操作会略有不同。2003版本的操作流程为:视图→工具栏→控件工具箱→其他控件;2007版本的操作流程为:单击PowerPoint选项,单击常规→在功能区显示“开发工具”选项卡。在功能区开发工具下,单击其他控件。

以上两个版本,都单击选择3DVIA ComposerPlayer ActiveX;点击后,在 Word中的合适位置,拖动放置一个窗口。这个窗口就是在 Word中展示 SolidWorks Composer文件的视区。

鼠标右键单击对象,并选择3DVIA Composer PlayerActiveX/Properties,如图 1所示。

在 General标签中,File name是浏览要展示的 SMG文件,将我们需要引入的文件添加进来。

勾选 Pack 3DVIA Composer document选项,我们的方法其实是引入 SolidWorks Composer的文件到 Word中,选择该选项,可以将文件完全嵌入 Word中,以后使用的时候只需要单独保存 Word就可以,不需要将 SMG文件和 Word一起保存。如果没有勾选这个选项,保存 Word的时候,要连同 SMG一同保存,而且要处于同一个文件路径下,虽然看起来很复杂,但是这种设置可以让打开 Word的时候读取动画的速度加快了,针对这个选项还需要用户亲自体验一下,选择是否应用。如图 2所示。

在 Layout标签中(图 3),可选择哪些工具要开放在操作窗口中,在这里我们选择全部关闭,这样视图中的SMG文件只能移动和选择,没有其他工具条。去除 Layout的选项界面后,如图 4所示。

注意:以上操作一定是在控件设计模式下完成,退出设计模式后(图 5),可以浏览到视图。

当然,我们也可以实现在 Word中,还原基本的 SMG文件操作环境,比如一些光源、环境的设置,技术渲染的模式设置等,这些都可以在 Layout的中选择相应的选项,然后生成。如图 6所示。

三、通过 API增加按钮

回到设计模式,在开发工具中,添加一个 Active控件的命令按钮(图 7)。这是在 Word中添加一个可以点击的按钮,来完成我们想要实现的动作。这个方法同样适用于PPT、Excel等工具。

添加一个按钮后,在按钮上右键单机属性,可以填写按钮的显示名称(Caption中填写),比如我们想更换部件的颜色,可以设定三个按钮,以本案例中的虎式坦克模型的不同颜色炮管为例,分别命名成“红色炮管”、“绿色炮管”和“蓝色炮管”;在属性中,可以设置按钮的其他文字显示细节,比如字体、大小和颜色,大家可以按照喜好进行按钮的设置。双击按钮“红色炮管”打开 Microsoftvisual basic,在 private sub和 end sub之间输入:DS3DVIAPlayerActiveX1.GoToConfiguration "c"。

四、解析 API格式

DS3DVIAPlayerActiveX1是所有作用在 3DVIA Composer Active控件下的 API明了的前缀,意味着每次添加的 API接口如果是调用 3DVIA Composer Active控件,则必须都要使用这个前缀。GoToConfiguration是提供的负责转换配置的 API,在这里可以理解成转换视图。所以 GoToConfiguration"c"可以理解成转换到视图 C。

这里应用了一个在 SMG文件中,名称是 C的视图。如图 8所示。

与“红色炮管”同理,我可以依次为“绿色炮管”、“蓝色炮管”添加 API,但是需要注意的是,同一个按钮里,添加不同的 API需要将 DS3DVIAPlayerActiveX1按照添加的控件顺序,变成 DS3DVIAPlayerActiveX2、DS3DVIAPlayerActiveX3。注意:不同按钮之间不用变换顺序。

设置完成后,我们就可以在 Word中,通过点击按钮来给虎式坦克更换炮管的颜色了,如图 9所示。当然这只是一个简单的示范,利用 API的接口,我们可以处理更多的动作,比如视图的切换,固定配置的展示等。

五、调用其他 API

SolidWorks Composer提供了诸多可方便添加的 API接口,调用和查询 API的方法也很简单,在 SolidWorksComposer软件中,找到帮助,找到编程向导,如图10所示。

找到 SolidWorks Composer player active API的方法如图 11所示。

SolidWorks Composer player active API提供了很多不同功能的API 接口,如图12 所示。

这里面的接口示意可以根据英文直接理解其含义,比如ChangMarker 是完成SMG 中的标记变化, 通常我们在SMG 建立不同的标记来记录一段产品动画不同时期的状态,如果选择了ChangMarker 实际上就是在Word 或者PPT 中增加了“下一步”的操作。这里不详细解释每种API 的作用了,感兴趣大家可以自己试试。

六、结语

API外汇保证金交易 篇4

目前市场上炒作API外汇的教程和方法很多,有些侧重于基本面,有些侧重于技术面,但无论从消息面还是技术面来看,都有其局限性,首先:消息面的影响层面较弱,只能局部影响到汇率的波动,但日常的震荡和走势更多的取决于全球投资人的预判;技术面则更为复杂,而且外汇交易市场本质上是一个混沌状态,没有100%的自然规律可言,如果一味误信技术则可能导致判断完全失误;,目前市场比较高端的交易方式为自发式针对性交易系统的打造:也就是打造一套属于自己的个人风格的外汇交易系统,系统即一系列规则综合,考虑了所有的资本投入比与风险控制机制,而不仅仅是某个技巧,利用外汇交易系统,普通人做外汇也可以赚的盆满钵满,而交易系统里公认做的最好的目前就是API外汇理财平台,在2012被评为“最佳外汇交易系统”

若保证金融资比例为100倍,即最低的保证金要求是1%,投资者只要1000美元,就可以进行高达100,000美元的交易,充分利用了以小搏大的杠杆效用。除了资金放大之外,外汇保证金投资另一项最吸引人的特色是可以双向操作,您可以在货币上升时买入获利(做多头),也可以在货币下跌时卖出获利(做空头),从而不必受到所谓的熊市中无法赚钱的限制,提供了更大的盈利空间和机会。随着国际间的贸易接触日趋频繁以及全球金融市场之整合,外汇市场实际上已成为全球最大的金融交易市场,在资金跨国性的流动程序中扮演着关键性的角色。因其连贯全球五大洲,24小时不停的交易型态,公平透明的市场行为及顺畅的流动性,T+0的清算制度,早已成为2013年以来热门的投资理财工具,以及厂商因应对汇率变化,规避风险之最佳通道。然而汇率如以全额交易波动幅度不大(平均每日振幅0.7-1.5%),投资报酬较小,故一般外汇交易金额很大,而非多数小额投资人所能运用。而外汇保证金制度,以杠杆原理,使外汇市场日趋活络,成交量剧增。无论做为企业的资本投资还是个人理财的多元化都不视为一种全新的理念。

保证金交易就是投资者以银行、造市商或经纪商提供的融资来进行外汇交易。一般的融资比例都在20倍以上,即投资者的资金可以放大20倍来进行交易。融资的比例越大,客户需要付出的资金也越少,例如,交易商提供的保证金融资比例是400倍,即最低的保证金要求是0.25%,投资者只要25美圆,就可以进行高达10,000美圆的交易,充分利用了以小搏大的杠杆效用。

除了资金放大之外,外汇保证金投资另一项最吸引人的特色是可以双向操作,您可以在货币上升时买入获利(做多头),也可以在货币下跌时卖出获利(做空头),从而不必受到所谓的熊市中无法赚钱的限制。

api应用 篇5

Sqlite3 的确很好用,小巧、速度快。但是因为非微软的产品,帮助文档总觉得不够。这些天再次研究它,又有一些收获,这里把我对 sqlite3 的研究列出来,以备忘记

前序:... 1

一、版本... 1

二、基本编译... 2

三、SQLITE操作入门... 2

(1) 基本流程... 2

(2) SQL语句操作... 4

(3) 操作二进制... 8

(4) 事务处理... 10

四、给数据库加密... 10

五、后记... 25

前序:

Sqlite3 的确很好用。小巧、速度快。但是因为非微软的产品,帮助文档总觉得不够。这些天再次研究它,又有一些收获,这里把我对 sqlite3 的研究列出来,以备忘记。

这里要注明,我是一个跨平台专注者,并不喜欢只用 windows平台。我以前的工作就是为 unix平台写代码。下面我所写的东西,虽然没有验证,但是我已尽量不使用任何 windows 的东西,只使用标准 C 或标准C++。但是,我没有尝试过在别的系统、别的编译器下编译,因此下面的叙述如果不正确,则留待以后修改。

下面我的代码仍然用 VC 编写,因为我觉得VC是一个很不错的IDE,可以加快代码编写速度(例如配合 Vassist )。下面我所说的编译环境,是VC。如果读者觉得自己习惯于 unix 下用 vi 编写代码速度较快,可以不用管我的说明,只需要符合自己习惯即可,因为我用的是标准 C 或 C++ 。不会给任何人带来不便。

一、版本

从 www.sqlite.org 网站可下载到最新的 sqlite 代码和编译版本。我写此文章时,最新代码是 3.3.17 版本。

很久没有去下载 sqlite 新代码,因此也不知道 sqlite 变化这么大。以前很多文件,现在全部合并成一个 sqlite3.c 文件。如果单独用此文件,是挺好的,省去拷贝一堆文件还担心有没有遗漏。但是也带来一个问题:此文件太大,快接近7万行代码,VC开它整个机器都慢下来了。如果不需要改它代码,也就不需要打开 sqlite3.c 文件,机器不会慢。但是,下面我要写通过修改 sqlite 代码完成加密功能,那时候就比较痛苦了。如果个人水平较高,建议用些简单的编辑器来编辑,例如 UltraEdit 或 Notepad 。速度会快很多。

二、基本编译

这个不想多说了,在 VC 里新建 dos 控制台空白工程,把 sqlite3.c 和 sqlite3.h 添加到工程,再新建一个 main.cpp 文件。在里面写:

代码如下:

extern “C”

{

#include “./sqlite3.h”

};

int main( int , char** )

{

return 0;

}

为什么要 extern “C” ?如果问这个问题,我不想说太多,这是C++的基础。要在 C++ 里使用一段 C 的代码,必须要用 extern “C” 括起来。C++跟 C虽然语法上有重叠,但是它们是两个不同的东西,内存里的布局是完全不同的,在C++编译器里不用extern “C”括起C代码,会导致编译器不知道该如何为 C 代码描述内存布局。

可能在 sqlite3.c 里人家已经把整段代码都 extern “C” 括起来了,但是你遇到一个 .c 文件就自觉的再括一次,也没什么不好。

基本工程就这样建立起来了。编译,可以通过。但是有一堆的 warning。可以不管它。

三、SQLITE操作入门

sqlite提供的是一些C函数接口,你可以用这些函数操作数据库。通过使用这些接口,传递一些标准 sql 语句(以 char * 类型)给 sqlite 函数,sqlite 就会为你操作数据库。

sqlite 跟MS的access一样是文件型数据库,就是说,一个数据库就是一个文件,此数据库里可以建立很多的表,可以建立索引、触发器等等,但是,它实际上得到的就是一个文件。备份这个文件就备份了整个数据库。

sqlite 不需要任何数据库引擎,这意味着如果你需要 sqlite 来保存一些用户数据,甚至都不需要安装数据库(如果你做个小软件还要求人家必须装了sqlserver 才能运行,那也太黑心了)。

下面开始介绍数据库基本操作。

(1) 基本流程

i.1 关键数据结构

sqlite 里最常用到的是 sqlite3 * 类型。从数据库打开开始,sqlite就要为这个类型准备好内存,直到数据库关闭,整个过程都需要用到这个类型。当数据库打开时开始,这个类型的变量就代表了你要操作的数据库。下面再详细介绍。

i.2 打开数据库

int sqlite3_open( 文件名, sqlite3 ** );

用这个函数开始数据库操作。

需要传入两个参数,一是数据库文件名,比如:c://DongChunGuang_Database.db。

文件名不需要一定存在,如果此文件不存在,sqlite 会自动建立它。如果它存在,就尝试把它当数据库文件来打开。

sqlite3 ** 参数即前面提到的关键数据结构。这个结构底层细节如何,你不要关它。

函数返回值表示操作是否正确,如果是 SQLITE_OK 则表示操作正常。相关的返回值sqlite定义了一些宏。具体这些宏的含义可以参考 sqlite3.h 文件。里面有详细定义(顺便说一下,sqlite3 的代码注释率自称是非常高的,实际上也的确很高。只要你会看英文,sqlite 可以让你学到不少东西)。

下面介绍关闭数据库后,再给一段参考代码。

i.3 关闭数据库

int sqlite3_close(sqlite3 *);

前面如果用 sqlite3_open 开启了一个数据库,结尾时不要忘了用这个函数关闭数据库。

下面给段简单的代码:

代码如下:

extern “C”

{

#include “./sqlite3.h”

};

int main( int , char** )

{

sqlite3 * db = NULL; //声明sqlite关键结构指针

int result;

//打开数据库

//需要传入 db 这个指针的指针,因为 sqlite3_open 函数要为这个指针分配内存,还要让db指针指向这个内存区

result = sqlite3_open( “c://Dcg_database.db”, &db );

if( result != SQLITE_OK )

{

//数据库打开失败

return -1;

}

//数据库操作代码

//…

//数据库打开成功

//关闭数据库

sqlite3_close( db );

return 0;

}

这就是一次数据库操作过程。

(2) SQL语句操作

本节介绍如何用sqlite 执行标准 sql 语法。

i.1 执行sql语句

int sqlite3_exec(sqlite3*, const char *sql, sqlite3_callback, void *, char **errmsg );

这就是执行一条 sql 语句的函数。

第1个参数不再说了,是前面open函数得到的指针。说了是关键数据结构。

第2个参数const char *sql 是一条 sql 语句,以/0结尾。

第3个参数sqlite3_callback 是回调,当这条语句执行之后,sqlite3会去调用你提供的这个函数。(什么是回调函数,自己找别的资料学习)

第4个参数void * 是你所提供的指针,你可以传递任何一个指针参数到这里,这个参数最终会传到回调函数里面,如果不需要传递指针给回调函数,可以填NULL。等下我们再看回调函数的写法,以及这个参数的使用。

第5个参数char ** errmsg 是错误信息。注意是指针的指针。sqlite3里面有很多固定的错误信息。执行 sqlite3_exec 之后,执行失败时可以查阅这个指针(直接 printf(“%s/n”,errmsg))得到一串字符串信息,这串信息告诉你错在什么地方。sqlite3_exec函数通过修改你传入的指针的指针,把你提供的指针指向错误提示信息,这样sqlite3_exec函数外面就可以通过这个 char*得到具体错误提示。

说明:通常,sqlite3_callback 和它后面的 void * 这两个位置都可以填 NULL。填NULL表示你不需要回调。比如你做 insert 操作,做 delete 操作,就没有必要使用回调。而当你做 select 时,就要使用回调,因为 sqlite3 把数据查出来,得通过回调告诉你查出了什么数据。

i.2 exec 的回调

typedef int (*sqlite3_callback)(void*,int,char**, char**);

你的回调函数必须定义成上面这个函数的类型。下面给个简单的例子:

代码如下:

//sqlite3的回调函数

// sqlite 每查到一条记录,就调用一次这个回调

int LoadMyInfo( void * para, int n_column, char ** column_value, char ** column_name )

{

//para是你在 sqlite3_exec 里传入的 void * 参数

//通过para参数,你可以传入一些特殊的指针(比如类指针、结构指针),然后在这里面强制转换成对应的类型(这里面是void*类型,必须强制转换成你的类型才可用)。然后操作这些数据

//n_column是这一条记录有多少个字段 (即这条记录有多少列)

// char ** column_value 是个关键值,查出来的数据都保存在这里,它实际上是个1维数组(不要以为是2维数组),每一个元素都是一个 char * 值,是一个字段内容(用字符串来表示,以/0结尾)

//char ** column_name 跟 column_value是对应的,表示这个字段的字段名称

//这里,我不使用 para 参数。忽略它的存在.

int i;

printf( “记录包含 %d 个字段/n”, n_column );

for( i = 0 ; i < n_column; i ++ )

{

printf( “字段名:%s ß>字段值:%s/n”, column_name[i], column_value[i] );

}

printf( “------------------/n“ );

return 0;

}

int main( int , char ** )

{

sqlite3 * db;

int result;

char * errmsg = NULL;

result = sqlite3_open( “c://Dcg_database.db”, &db );

if( result != SQLITE_OK )

{

//数据库打开失败

return -1;

}

//数据库操作代码

//创建一个测试表,表名叫 MyTable_1,有2个字段: ID 和 name。其中ID是一个自动增加的类型,以后insert时可以不去指定这个字段,它会自己从0开始增加

result = sqlite3_exec( db, “create table MyTable_1( ID integer primary key autoincrement, name nvarchar(32) )”, NULL, NULL, errmsg );

if(result != SQLITE_OK )

{

printf( “创建表失败,错误码:%d,错误原因:%s/n”, result, errmsg );

}

//插入一些记录

result = sqlite3_exec( db, “insert into MyTable_1( name ) values ( ‘走路‘ )”, 0, 0, errmsg );

if(result != SQLITE_OK )

{

printf( “插入记录失败,错误码:%d,错误原因:%s/n”, result, errmsg );

}

result = sqlite3_exec( db, “insert into MyTable_1( name ) values ( ‘骑单车‘ )”, 0, 0, errmsg );

if(result != SQLITE_OK )

{

printf( “插入记录失败,错误码:%d,错误原因:%s/n”, result, errmsg );

}

result = sqlite3_exec( db, “insert into MyTable_1( name ) values ( ‘坐汽车‘ )”, 0, 0, errmsg );

if(result != SQLITE_OK )

{

printf( “插入记录失败,错误码:%d,错误原因:%s/n”, result, errmsg );

}

//开始查询数据库

result = sqlite3_exec( db, “select * from MyTable_1”, LoadMyInfo, NULL, errmsg );

//关闭数据库

sqlite3_close( db );

return 0;

}

通过上面的例子,应该可以知道如何打开一个数据库,如何做数据库基本操作。

有这些知识,基本上可以应付很多数据库操作了。

i.3 不使用回调查询数据库

上面介绍的 sqlite3_exec 是使用回调来执行 select 操作。还有一个方法可以直接查询而不需要回调。但是,我个人感觉还是回调好,因为代码可以更加整齐,只不过用回调很麻烦,你得声明一个函数,如果这个函数是类成员函数,你还不得不把它声明成 static 的(要问为什么?这又是C++基础了。C++成员函数实际上隐藏了一个参数:this,C++调用类的成员函数的时候,隐含把类指针当成函数的第一个参数传递进去。结果,这造成跟前面说的 sqlite 回调函数的参数不相符。只有当把成员函数声明成 static 时,它才没有多余的隐含的this参数)。

虽然回调显得代码整齐,但有时候你还是想要非回调的 select 查询。这可以通过 sqlite3_get_table 函数做到。

int sqlite3_get_table(sqlite3*, const char *sql, char ***resultp, int *nrow, int *ncolumn, char **errmsg );

第1个参数不再多说,看前面的例子。

第2个参数是 sql 语句,跟 sqlite3_exec 里的 sql 是一样的。是一个很普通的以/0结尾的char *字符串。

第3个参数是查询结果,它依然一维数组(不要以为是二维数组,更不要以为是三维数组)。它内存布局是:第一行是字段名称,后面是紧接着是每个字段的值。下面用例子来说事。

第4个参数是查询出多少条记录(即查出多少行)。

第5个参数是多少个字段(多少列)。

第6个参数是错误信息,跟前面一样,这里不多说了。

下面给个简单例子:

代码如下:

int main( int , char ** )

{

sqlite3 * db;

int result;

char * errmsg = NULL;

char **dbResult; //是 char ** 类型,两个*号

int nRow, nColumn;

int i , j;

int index;

result = sqlite3_open( “c://Dcg_database.db”, &db );

if( result != SQLITE_OK )

{

//数据库打开失败

return -1;

}

//数据库操作代码

//假设前面已经创建了 MyTable_1 表

//开始查询,传入的 dbResult 已经是 char **,这里又加了一个 & 取地址符,传递进去的就成了 char ***

result = sqlite3_get_table( db, “select * from MyTable_1”, &dbResult, &nRow, &nColumn, &errmsg );

if( SQLITE_OK == result )

{

//查询成功

index = nColumn; //前面说过 dbResult 前面第一行数据是字段名称,从 nColumn 索引开始才是真正的数据

printf( “查到%d条记录/n”, nRow );

for( i = 0; i < nRow ; i++ )

{

printf( “第 %d 条记录/n”, i+1 );

for( j = 0 ; j < nColumn; j++ )

{

printf( “字段名:%s ß>字段值:%s/n”, dbResult[j], dbResult [index] );

++index; // dbResult 的字段值是连续的,从第0索引到第 nColumn - 1索引都是字段名称,从第 nColumn 索引开始,后面都是字段值,它把一个二维的表(传统的行列表示法)用一个扁平的形式来表示

}

printf( “-------/n” );

}

}

//到这里,不论数据库查询是否成功,都释放 char** 查询结果,使用 sqlite 提供的功能来释放

sqlite3_free_table( dbResult );

//关闭数据库

sqlite3_close( db );

return 0;

}

到这个例子为止,sqlite3 的常用用法都介绍完了。

用以上的方法,再配上 sql 语句,完全可以应付绝大多数数据库需求。

但有一种情况,用上面方法是无法实现的:需要insert、select 二进制。当需要处理二进制数据时,上面的方法就没办法做到。下面这一节说明如何插入二进制数据

(2) 操作二进制

sqlite 操作二进制数据需要用一个辅助的数据类型:sqlite3_stmt * 。

这个数据类型记录了一个“sql语句”。为什么我把 “sql语句” 用双引号引起来?因为你可以把 sqlite3_stmt * 所表示的内容看成是 sql语句,但是实际上它不是我们所熟知的sql语句。它是一个已经把sql语句解析了的、用sqlite自己标记记录的内部数据结构。

正因为这个结构已经被解析了,所以你可以往这个语句里插入二进制数据。当然,把二进制数据插到 sqlite3_stmt 结构里可不能直接 memcpy ,也不能像 std::string 那样用 + 号。必须用 sqlite 提供的函数来插入。

i.1 写入二进制

下面说写二进制的步骤。

要插入二进制,前提是这个表的字段的类型是 blob 类型。我假设有这么一张表:

create table Tbl_2( ID integer, file_content blob )

首先声明

sqlite3_stmt * stat;

然后,把一个 sql 语句解析到 stat 结构里去:

sqlite3_prepare( db, “insert into Tbl_2( ID, file_content) values( 10, ? )”, -1, &stat, 0 );

上面的函数完成 sql 语句的解析。第一个参数跟前面一样,是个 sqlite3 * 类型变量,第二个参数是一个 sql 语句。

这个 sql 语句特别之处在于 values 里面有个 ? 号。在sqlite3_prepare函数里,?号表示一个未定的值,它的值等下才插入。

第三个参数我写的是-1,这个参数含义是前面 sql 语句的长度。如果小于0,sqlite会自动计算它的长度(把sql语句当成以/0结尾的字符串)。

第四个参数是 sqlite3_stmt 的指针的指针。解析以后的sql语句就放在这个结构里。

第五个参数我也不知道是干什么的。为0就可以了。

如果这个函数执行成功(返回值是 SQLITE_OK 且 stat 不为NULL ),那么下面就可以开始插入二进制数据。

sqlite3_bind_blob( stat, 1, pdata, (int)(length_of_data_in_bytes), NULL ); // pdata为数据缓冲区,length_of_data_in_bytes为数据大小,以字节为单位

这个函数一共有5个参数。

第1个参数:是前面prepare得到的 sqlite3_stmt * 类型变量。

第2个参数:?号的索引。前面prepare的sql语句里有一个?号,假如有多个?号怎么插入?方法就是改变 bind_blob 函数第2个参数。这个参数我写1,表示这里插入的值要替换 stat 的第一个?号(这里的索引从1开始计数,而非从0开始)。如果你有多个?号,就写多个 bind_blob 语句,并改变它们的第2个参数就替换到不同的?号。如果有?号没有替换,sqlite为它取值null。

第3个参数:二进制数据起始指针。

第4个参数:二进制数据的长度,以字节为单位。

第5个参数:是个析够回调函数,告诉sqlite当把数据处理完后调用此函数来析够你的数据。这个参数我还没有使用过,因此理解也不深刻。但是一般都填NULL,需要释放的内存自己用代码来释放。

bind完了之后,二进制数据就进入了你的“sql语句”里了。你现在可以把它保存到数据库里:

int result = sqlite3_step( stat );

通过这个语句,stat 表示的sql语句就被写到了数据库里。

最后,要把 sqlite3_stmt 结构给释放:

sqlite3_finalize( stat ); //把刚才分配的内容析构掉

i.2 读出二进制

下面说读二进制的步骤。

跟前面一样,先声明 sqlite3_stmt * 类型变量:

sqlite3_stmt * stat;

然后,把一个 sql 语句解析到 stat 结构里去:

sqlite3_prepare( db, “select * from Tbl_2”, -1, &stat, 0 );

当 prepare 成功之后(返回值是 SQLITE_OK ),开始查询数据。

int result = sqlite3_step( stat );

这一句的返回值是 SQLITE_ROW 时表示成功(不是 SQLITE_OK )。

你可以循环执行 sqlite3_step 函数,一次 step 查询出一条记录。直到返回值不为 SQLITE_ROW 时表示查询结束。

然后开始获取第一个字段:ID 的值。ID是个整数,用下面这个语句获取它的值:

int id = sqlite3_column_int( stat, 0 ); //第2个参数表示获取第几个字段内容,从0开始计算,因为我的表的ID字段是第一个字段,因此这里我填0

下面开始获取 file_content 的值,因为 file_content 是二进制,因此我需要得到它的指针,还有它的长度:

const void * pFileContent = sqlite3_column_blob( stat, 1 );

int len = sqlite3_column_bytes( stat, 1 );

这样就得到了二进制的值。

把 pFileContent 的内容保存出来之后,不要忘了释放 sqlite3_stmt 结构:

sqlite3_finalize( stat ); //把刚才分配的内容析构掉

i.3 重复使用 sqlite3_stmt 结构

如果你需要重复使用 sqlite3_prepare 解析好的 sqlite3_stmt 结构,需要用函数: sqlite3_reset。

result = sqlite3_reset(stat);

这样, stat 结构又成为 sqlite3_prepare 完成时的状态,你可以重新为它 bind 内容。

(4) 事务处理

sqlite 是支持事务处理的。如果你知道你要同步删除很多数据,不仿把它们做成一个统一的事务。

通常一次 sqlite3_exec 就是一次事务,如果你要删除1万条数据,sqlite就做了1万次:开始新事务->删除一条数据->提交事务->开始新事务->… 的过程。这个操作是很慢的。因为时间都花在了开始事务、提交事务上。

你可以把这些同类操作做成一个事务,这样如果操作错误,还能够回滚事务。

事务的操作没有特别的接口函数,它就是一个普通的 sql 语句而已:

分别如下:

代码如下:

int result;

result = sqlite3_exec( db, “begin transaction”, 0, 0, &zErrorMsg ); //开始一个事务

result = sqlite3_exec( db, “commit transaction”, 0, 0, &zErrorMsg ); //提交事务

result = sqlite3_exec( db, “rollback transaction”, 0, 0, &zErrorMsg ); //回滚事务

一、给数据库加密

前面所说的内容网上已经有很多资料,虽然比较零散,但是花点时间也还是可以找到的。现在要说的这个――数据库加密,资料就很难找。也可能是我操作水平不够,找不到对应资料。但不管这样,我还是通过网上能找到的很有限的资料,探索出了给sqlite数据库加密的完整步骤。

这里要提一下,虽然 sqlite 很好用,速度快、体积小巧。但是它保存的文件却是明文的。若不信可以用 NotePad 打开数据库文件瞧瞧,里面 insert 的内容几乎一览无余。这样赤裸裸的展现自己,可不是我们的初衷。当然,如果你在嵌入式系统、智能手机上使用 sqlite,最好是不加密,因为这些系统运算能力有限,你做为一个新功能提供者,不能把用户有限的运算能力全部花掉。

Sqlite为了速度而诞生。因此Sqlite本身不对数据库加密,要知道,如果你选择标准AES算法加密,那么一定有接近50%的时间消耗在加解密算法上,甚至更多(性能主要取决于你算法编写水平以及你是否能使用cpu提供的底层运算能力,比如MMX或sse系列指令可以大幅度提升运算速度)。

Sqlite免费版本是不提供加密功能的,当然你也可以选择他们的收费版本,那你得支付块钱,而且是USD。我这里也不是说支付钱不好,如果只为了数据库加密就去支付2000块,我觉得划不来。因为下面我将要告诉你如何为免费的Sqlite扩展出加密模块――自己动手扩展,这是Sqlite允许,也是它提倡的。

那么,就让我们一起开始为 sqlite3.c 文件扩展出加密模块。

i.1 必要的宏

通过阅读 Sqlite 代码(当然没有全部阅读完,6万多行代码,没有一行是我习惯的风格,我可没那么多眼神去看),我搞清楚了两件事:

Sqlite是支持加密扩展的;

需要 #define 一个宏才能使用加密扩展。

这个宏就是

SQLITE_HAS_CODEC。

你在代码最前面(也可以在 sqlite3.h 文件第一行)定义:

#ifndef SQLITE_HAS_CODEC

#define SQLITE_HAS_CODEC

#endif

如果你在代码里定义了此宏,但是还能够正常编译,那么应该是操作没有成功。因为你应该会被编译器提示有一些函数无法链接才对。如果你用的是 VC 2003,你可以在“解决方案”里右键点击你的工程,然后选“属性”,找到“C/C ”,再找到“命令行”,在里面手工添加“/D “SQLITE_HAS_CODEC””。

定义了这个宏,一些被 Sqlite 故意屏蔽掉的代码就被使用了。这些代码就是加解密的接口。

尝试编译,vc会提示你有一些函数无法链接,因为找不到他们的实现。

如果你也用的是VC2003,那么会得到下面的提示:

error LNK: 无法解析的外部符号 _sqlite3CodecGetKey ,该符号在函数 _attachFunc 中被引用

error LNK2019: 无法解析的外部符号 _sqlite3CodecAttach ,该符号在函数 _attachFunc 中被引用

error LNK2019: 无法解析的外部符号 _sqlite3_activate_see,该符号在函数 _sqlite3Pragma 中被引用

error LNK2019: 无法解析的外部符号 _sqlite3_key ,该符号在函数 _sqlite3Pragma 中被引用

fatal error LNK1120: 4 个无法解析的外部命令

这是正常的,因为Sqlite只留了接口而已,并没有给出实现。

下面就让我来实现这些接口。

i.2 自己实现加解密接口函数

如果真要我从一份 www.sqlite.org 网上down下来的 sqlite3.c 文件,直接摸索出这些接口的实现,我认为我还没有这个能力。

好在网上还有一些代码已经实现了这个功能。通过参照他们的代码以及不断编译中vc给出的错误提示,最终我把整个接口整理出来,

实现这些预留接口不是那么容易,要重头说一次怎么回事很困难。我把代码都写好了,直接把他们按我下面的说明拷贝到 sqlite3.c 文件对应地方即可。我在下面也提供了sqlite3.c 文件,可以直接参考或取下来使用。

这里要说一点的是,我另外新建了两个文件:crypt.c和crypt.h。

其中crypt.h如此定义:

#ifndef DCG_SQLITE_CRYPT_FUNC_

#define DCG_SQLITE_CRYPT_FUNC_

***********/

int My_DeEncrypt_Func( unsigned char * pData, unsigned int data_len, const char * key, unsigned int len_of_key );

#endif

其中的 crypt.c 如此定义:

#include “./crypt.h”

#include “memory.h”

int My_Encrypt_Func( unsigned char * pData, unsigned int data_len, const char * key, unsigned int len_of_key )

{

return 0;

}

int My_DeEncrypt_Func( unsigned char * pData, unsigned int data_len, const char * key, unsigned int len_of_key )

{

return 0;

}

这个文件很容易看,就两函数,一个加密一个解密。传进来的参数分别是待处理的数据、数据长度、密钥、密钥长度。

处理时直接把结果作用于 pData 指针指向的内容。

你需要定义自己的加解密过程,就改动这两个函数,其它部分不用动。扩展起来很简单。

这里有个特点,data_len 一般总是 1024 字节。正因为如此,你可以在你的算法里使用一些特定长度的加密算法,比如AES要求被加密数据一定是128位(16字节)长。这个1024不是碰巧,而是 Sqlite 的页定义是1024字节,在sqlite3.c文件里有定义:

# define SQLITE_DEFAULT_PAGE_SIZE 1024

你可以改动这个值,不过还是建议没有必要不要去改它。

上面写了两个扩展函数,如何把扩展函数跟 Sqlite 挂接起来,这个过程说起来比较麻烦。我直接贴代码。

分3个步骤。

首先,在 sqlite3.c 文件顶部,添加下面内容:

#ifdef SQLITE_HAS_CODEC

#include “./crypt.h”

void sqlite3pager_free_codecarg(void *pArg);

#endif

这个函数之所以要在 sqlite3.c 开头声明,是因为下面在 sqlite3.c 里面某些函数里要插入这个函数调用。所以要提前声明。

其次,在sqlite3.c文件里搜索“sqlite3PagerClose”函数,要找到它的实现代码(而不是声明代码)。

实现代码里一开始是:

#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT

ThreadData *pTsd = sqlite3ThreadData;

assert( pPager );

assert( pTsd && pTsd->nAlloc );

#endif

需要在这部分后面紧接着插入:

#ifdef SQLITE_HAS_CODEC

sqlite3pager_free_codecarg(pPager->pCodecArg);

#endif

这里要注意,sqlite3PagerClose 函数大概也是 3.3.17版本左右才改名的,以前版本里是叫 “sqlite3pager_close”。因此你在老版本sqlite代码里搜索“sqlite3PagerClose”是搜不到的。

类似的还有“sqlite3pager_get”、“sqlite3pager_unref”、“sqlite3pager_write”、“sqlite3pager_pagecount”等都是老版本函数,它们在 pager.h 文件里定义。新版本对应函数是在 sqlite3.h 里定义(因为都合并到 sqlite3.c和sqlite3.h两文件了)。所以,如果你在使用老版本的sqlite,先看看 pager.h 文件,这些函数不是消失了,也不是新蹦出来的,而是老版本函数改名得到的。

最后,往sqlite3.c 文件下找。找到最后一行:

在这一行后面,接上本文最下面的代码段。

这些代码很长,我不再解释,直接接上去就得了。

唯一要提的是 DeriveKey 函数。这个函数是对密钥的扩展。比如,你要求密钥是128位,即是16字节,但是如果用户只输入 1个字节呢?2个字节呢?或输入50个字节呢?你得对密钥进行扩展,使之符合16字节的要求。

DeriveKey 函数就是做这个扩展的。有人把接收到的密钥求md5,这也是一个办法,因为md5运算结果固定16字节,不论你有多少字符,最后就是16字节。这是md5算法的特点。但是我不想用md5,因为还得为它添加包含一些 md5 的.c或.cpp文件。我不想这么做。我自己写了一个算法来扩展密钥,很简单的算法。当然,你也可以使用你的扩展方法,也而可以使用 md5 算法。只要修改 DeriveKey 函数就可以了。

在 DeriveKey 函数里,只管申请空间构造所需要的密钥,不需要释放,因为在另一个函数里有释放过程,而那个函数会在数据库关闭时被调用。参考我的 DeriveKey 函数来申请内存。

这里我给出我已经修改好的 sqlite3.c 和 sqlite3.h 文件。

如果太懒,就直接使用这两个文件,编译肯定能通过,运行也正常。当然,你必须按我前面提的,新建 crypt.h 和 crypt.c 文件,而且函数要按我前面定义的要求来做。

i.3 加密使用方法:

现在,你代码已经有了加密功能。

你要把加密功能给用上,除了改 sqlite3.c 文件、给你工程添加 SQLITE_HAS_CODEC 宏,还得修改你的数据库调用函数。

前面提到过,要开始一个数据库操作,必须先 sqlite3_open 。

加解密过程就在 sqlite3_open 后面操作。

假设你已经 sqlite3_open 成功了,紧接着写下面的代码:

int i;

//添加、使用密码

i = sqlite3_key( db, “dcg”, 3 );

//修改密码

i = sqlite3_rekey( db, “dcg”, 0 );

用 sqlite3_key 函数来提交密码。

第1个参数是 sqlite3 * 类型变量,代表着用 sqlite3_open 打开的数据库(或新建数据库)。

第2个参数是密钥。

第3个参数是密钥长度。

用 sqlite3_rekey 来修改密码。参数含义同 sqlite3_key。

实际上,你可以在sqlite3_open函数之后,到 sqlite3_close 函数之前任意位置调用 sqlite3_key 来设置密码。

但是如果你没有设置密码,而数据库之前是有密码的,那么你做任何操作都会得到一个返回值:SQLITE_NOTADB,并且得到错误提示:“file is encrypted or is not a database”。

只有当你用 sqlite3_key 设置了正确的密码,数据库才会正常工作。

如果你要修改密码,前提是你必须先 sqlite3_open 打开数据库成功,然后 sqlite3_key 设置密钥成功,之后才能用 sqlite3_rekey 来修改密码。

如果数据库有密码,但你没有用 sqlite3_key 设置密码,那么当你尝试用 sqlite3_rekey 来修改密码时会得到 SQLITE_NOTADB 返回值。

如果你需要清空密码,可以使用:

//修改密码

i = sqlite3_rekey( db, NULL, 0 );

来完成密码清空功能。

i.4 sqlite3.c 最后添加代码段

代码如下:

#ifdef SQLITE_HAS_CODEC

#define CRYPT_OFFSET 8

typedef struct _CryptBlock

{

BYTE* ReadKey; // 读数据库和写入事务的密钥

BYTE* WriteKey; // 写入数据库的密钥

int PageSize; // 页的大小

BYTE* Data;

} CryptBlock, *LPCryptBlock;

#ifndef DB_KEY_LENGTH_BYTE

#define DB_KEY_LENGTH_BYTE 16

#endif

#ifndef DB_KEY_PADDING

#define DB_KEY_PADDING 0x33

#endif

void sqlite3CodecGetKey(sqlite3* db, int nDB, void** Key, int* nKey)

{

return ;

}

int sqlite3CodecAttach(sqlite3 *db, int nDb, const void *pKey, int nKeyLen);

void sqlite3_activate_see(const char* right )

{

return;

}

int sqlite3_key(sqlite3 *db, const void *pKey, int nKey);

int sqlite3_rekey(sqlite3 *db, const void *pKey, int nKey);

// 从用户提供的缓冲区中得到一个加密密钥

// 用户提供的密钥可能位数上满足不了要求,使用这个函数来完成密钥扩展

static unsigned char * DeriveKey(const void *pKey, int nKeyLen);

//创建或更新一个页的加密算法索引.此函数会申请缓冲区.

static LPCryptBlock CreateCryptBlock(unsigned char* hKey, Pager *pager, LPCryptBlock pExisting);

//加密/解密函数, 被pager调用

void * sqlite3Codec(void *pArg, unsigned char *data, Pgno nPageNum, int nMode);

//设置密码函数

int __stdcall sqlite3_key_interop(sqlite3 *db, const void *pKey, int nKeySize);

// 修改密码函数

int __stdcall sqlite3_rekey_interop(sqlite3 *db, const void *pKey, int nKeySize);

//销毁一个加密块及相关的缓冲区,密钥.

static void DestroyCryptBlock(LPCryptBlock pBlock);

static void * sqlite3pager_get_codecarg(Pager *pPager);

void sqlite3pager_set_codec(Pager *pPager,void *(*xCodec)(void*,void*,Pgno,int),void *pCodecArg );

//加密/解密函数, 被pager调用

void * sqlite3Codec(void *pArg, unsigned char *data, Pgno nPageNum, int nMode)

{

LPCryptBlock pBlock = (LPCryptBlock)pArg;

unsigned int dwPageSize = 0;

if (!pBlock) return data;

// 确保pager的页长度和加密块的页长度相等.如果改变,就需要调整.

if (nMode != 2)

{

PgHdr *pageHeader;

pageHeader = DATA_TO_PGHDR(data);

if (pageHeader->pPager->pageSize != pBlock->PageSize)

{

CreateCryptBlock(0, pageHeader->pPager, pBlock);

}

}

switch(nMode)

{

case 0: // Undo a “case 7” journal file encryption

case 2: //重载一个页

case 3: //载入一个页

if (!pBlock->ReadKey) break;

dwPageSize = pBlock->PageSize;

My_DeEncrypt_Func(data, dwPageSize, pBlock->ReadKey, DB_KEY_LENGTH_BYTE );

break;

case 6: //加密一个主数据库文件的页

if (!pBlock->WriteKey) break;

memcpy(pBlock->Data CRYPT_OFFSET, data, pBlock->PageSize);

data = pBlock->Data CRYPT_OFFSET;

dwPageSize = pBlock->PageSize;

My_Encrypt_Func(data , dwPageSize, pBlock->WriteKey, DB_KEY_LENGTH_BYTE );

break;

case 7: //加密事务文件的页

if (!pBlock->ReadKey) break;

memcpy(pBlock->Data CRYPT_OFFSET, data, pBlock->PageSize);

data = pBlock->Data CRYPT_OFFSET;

dwPageSize = pBlock->PageSize;

My_Encrypt_Func( data, dwPageSize, pBlock->ReadKey, DB_KEY_LENGTH_BYTE );

break;

}

return data;

}

//

销毁一个加密块及相关的缓冲区,密钥.

static void DestroyCryptBlock(LPCryptBlock pBlock)

{

//销毁读密钥.

if (pBlock->ReadKey){

sqliteFree(pBlock->ReadKey);

}

//如果写密钥存在并且不等于读密钥,也销毁.

if (pBlock->WriteKey && pBlock->WriteKey != pBlock->ReadKey){

sqliteFree(pBlock->WriteKey);

}

if(pBlock->Data){

sqliteFree(pBlock->Data);

}

//释放加密块.

sqliteFree(pBlock);

}

static void * sqlite3pager_get_codecarg(Pager *pPager)

{

return (pPager->xCodec) ? pPager->pCodecArg: NULL;

}

// 从用户提供的缓冲区中得到一个加密密钥

static unsigned char * DeriveKey(const void *pKey, int nKeyLen)

{

unsigned char * hKey = NULL;

int j;

if( pKey == NULL || nKeyLen == 0 )

{

return NULL;

}

hKey = sqliteMalloc( DB_KEY_LENGTH_BYTE 1 );

if( hKey == NULL )

{

return NULL;

}

hKey[ DB_KEY_LENGTH_BYTE ] = 0;

if( nKeyLen < DB_KEY_LENGTH_BYTE )

{

memcpy( hKey, pKey, nKeyLen ); //先拷贝得到密钥前面的部分

j = DB_KEY_LENGTH_BYTE - nKeyLen;

//补充密钥后面的部分

memset( hKey nKeyLen, DB_KEY_PADDING, j );

}

else

{ //密钥位数已经足够,直接把密钥取过来

memcpy( hKey, pKey, DB_KEY_LENGTH_BYTE );

}

return hKey;

}

//创建或更新一个页的加密算法索引.此函数会申请缓冲区.

static LPCryptBlock CreateCryptBlock(unsigned char* hKey, Pager *pager, LPCryptBlock pExisting)

{

LPCryptBlock pBlock;

if (!pExisting) //创建新加密块

{

pBlock = sqliteMalloc(sizeof(CryptBlock));

memset(pBlock, 0, sizeof(CryptBlock));

pBlock->ReadKey = hKey;

pBlock->WriteKey = hKey;

pBlock->PageSize = pager->pageSize;

pBlock->Data = (unsigned char*)sqliteMalloc(pBlock->PageSize CRYPT_OFFSET);

}

else //更新存在的加密块

{

pBlock = pExisting;

if ( pBlock->PageSize != pager->pageSize && !pBlock->Data){

sqliteFree(pBlock->Data);

pBlock->PageSize = pager->pageSize;

pBlock->Data = (unsigned char*)sqliteMalloc(pBlock->PageSize CRYPT_OFFSET);

}

}

memset(pBlock->Data, 0, pBlock->PageSize CRYPT_OFFSET);

return pBlock;

}

void sqlite3pager_set_codec(

Pager *pPager,

void *(*xCodec)(void*,void*,Pgno,int),

void *pCodecArg

)

{

pPager->xCodec = xCodec;

pPager->pCodecArg = pCodecArg;

}

int sqlite3_key(sqlite3 *db, const void *pKey, int nKey)

{

return sqlite3_key_interop(db, pKey, nKey);

}

int sqlite3_rekey(sqlite3 *db, const void *pKey, int nKey)

{

return sqlite3_rekey_interop(db, pKey, nKey);

}

int sqlite3CodecAttach(sqlite3 *db, int nDb, const void *pKey, int nKeyLen)

{

int rc = SQLITE_ERROR;

unsigned char* hKey = 0;

//如果没有指定密匙,可能标识用了主数据库的加密或没加密.

if (!pKey || !nKeyLen)

{

if (!nDb)

{

return SQLITE_OK; //主数据库, 没有指定密钥所以没有加密.

}

else //附加数据库,使用主数据库的密钥.

{

//获取主数据库的加密块并复制密钥给附加数据库使用

LPCryptBlock pBlock = (LPCryptBlock)sqlite3pager_get_codecarg(sqlite3BtreePager(db->aDb[0].pBt));

if (!pBlock) return SQLITE_OK; //主数据库没有加密

if (!pBlock->ReadKey) return SQLITE_OK; //没有加密

memcpy(pBlock->ReadKey, &hKey, 16);

}

}

else //用户提供了密码,从中创建密钥.

{

hKey = DeriveKey(pKey, nKeyLen);

}

//创建一个新的加密块,并将解码器指向新的附加数据库.

if (hKey)

{

LPCryptBlock pBlock = CreateCryptBlock(hKey, sqlite3BtreePager(db->aDb[nDb].pBt), NULL);

sqlite3pager_set_codec(sqlite3BtreePager(db->aDb[nDb].pBt), sqlite3Codec, pBlock);

rc = SQLITE_OK;

}

return rc;

}

// Changes the encryption key for an existing database.

int __stdcall sqlite3_rekey_interop(sqlite3 *db, const void *pKey, int nKeySize)

{

Btree *pbt = db->aDb[0].pBt;

Pager *p = sqlite3BtreePager(pbt);

LPCryptBlock pBlock = (LPCryptBlock)sqlite3pager_get_codecarg(p);

unsigned char * hKey = DeriveKey(pKey, nKeySize);

int rc = SQLITE_ERROR;

if (!pBlock && !hKey) return SQLITE_OK;

//重新加密一个数据库,改变pager的写密钥, 读密钥依旧保留.

if (!pBlock) //加密一个未加密的数据库

{

pBlock = CreateCryptBlock(hKey, p, NULL);

pBlock->ReadKey = 0; // 原始数据库未加密

sqlite3pager_set_codec(sqlite3BtreePager(pbt), sqlite3Codec, pBlock);

}

else // 改变已加密数据库的写密钥

{

pBlock->WriteKey = hKey;

}

// 开始一个事务

rc = sqlite3BtreeBeginTrans(pbt, 1);

if (!rc)

{

// 用新密钥重写所有的页到数据库。

Pgno nPage = sqlite3PagerPagecount(p);

Pgno nSkip = PAGER_MJ_PGNO(p);

void *pPage;

Pgno n;

for(n = 1; rc == SQLITE_OK && n <= nPage; n )

{

if (n == nSkip) continue;

rc = sqlite3PagerGet(p, n, &pPage);

if(!rc)

{

rc = sqlite3PagerWrite(pPage);

sqlite3PagerUnref(pPage);

}

}

}

// 如果成功,提交事务。

if (!rc)

{

rc = sqlite3BtreeCommit(pbt);

}

// 如果失败,回滚。

if (rc)

{

sqlite3BtreeRollback(pbt);

}

// 如果成功,销毁先前的读密钥。并使读密钥等于当前的写密钥。

if (!rc)

{

if (pBlock->ReadKey)

{

sqliteFree(pBlock->ReadKey);

}

pBlock->ReadKey = pBlock->WriteKey;

}

else// 如果失败,销毁当前的写密钥,并恢复为当前的读密钥。

{

if (pBlock->WriteKey)

{

sqliteFree(pBlock->WriteKey);

}

pBlock->WriteKey = pBlock->ReadKey;

}

// 如果读密钥和写密钥皆为空,就不需要再对页进行编解码。

// 销毁加密块并移除页的编解码器

if (!pBlock->ReadKey && !pBlock->WriteKey)

{

sqlite3pager_set_codec(p, NULL, NULL);

DestroyCryptBlock(pBlock);

}

return rc;

}

int __stdcall sqlite3_key_interop(sqlite3 *db, const void *pKey, int nKeySize)

{

return sqlite3CodecAttach(db, 0, pKey, nKeySize);

}

// 释放与一个页相关的加密块

void sqlite3pager_free_codecarg(void *pArg)

{

if (pArg)

DestroyCryptBlock((LPCryptBlock)pArg);

}

从淘客街谈淘客API如何优化 篇6

最近研究了一段时间淘宝API,正好手里空了一个www.taokezone.cn域名,就尝试着做一个淘客街来试试。很快就发现API做出来的淘客站千遍一律,内容重复率几乎100%,如何在众多网站中获得好的收录和权重呢? 很头疼:

1)选择稳定的服务器

大家都知道最近很多地方都在封网,既然决定做淘客,就要选择好一些的服务器,不然哪一天被封了就得不偿失。

2)做好PHP伪静态优化

虽然动态页搜索引擎也会收录,但通过伪静态优化可以自定义网页的名称,改善对搜索引擎的友好度,不然网络中同名同姓的人实在太多了,

3)做好站内链接

合理的站内链接更有利于提高PR值。另外有一个域名,从来么做过友情链接,但PR却在2个月内从0升到4,可见合理的站内链接多么有效。

4)给网站加上缓存

我设置Cache时间是24小时,虽然设置缓存后使用的空间大了很多,但速度的确快不少,而且还可以解决淘宝API每日使用次数的限制。对搜索引擎而言,每24小时的数据不同,也等于更新网站嘛。

网站刚刚上线,只是根据自己的能力,做了以上,也许算不上优化,希望能捡到天下掉下的金元宝。

控制API 篇7

当前, 企业IT发展有两大重要技术方向——云计算和SOA (以服务为导向的架构) 。云计算进一步打破软硬件间的边界, 实现IT资源的动态分配、弹性调整、智能监控等。SOA打破了软件系统间固有的边界, 使得具备无边界信息整合能力的IT架构成为可能。未来的云计算将包含支持SOA的IT基础设施, 包括中间件等, 实现云环境下的应用服务化、服务构件化、构件平台化、平台虚拟化、虚拟泛在化。

刘国强认为, 与过去相比, I T正扮演着业务服务代理人和应用程序组装者的角色。当软件即服务 (SaaS) 、平台即服务 (PaaS) 、基础设施即服务 (IaaS) 为计算能力提供访问时, IT将更加关注组合业务应用, 而非“购买—构建—管理”这一模式, 从而使IT的速度、创新、性能和成本或风险效率达到新的水平。为了成功实现这一转型, 企业CIO们需要充分利用以服务为导向的架构, 从而更有效的使用和控制API (应用程序编程接口) 。

开启一扇门

在云计算时代, IT基础设施变得不再重要, 而应用和服务将成为企业信息化的重点。而API所带来的全新商业模式很好的契合了这一发展要求。在这种商业模式下, 企业和开发者通过公共或私人API选择微功能部件, 这些微功能部件可以相对轻松地被整合或丢弃, 这对企业的IT人员来说是件美妙的事情。

API的目的是通过把程序内部的一些功能有限地向外开放使得应用之间可基于各自的利益分享数据, 同时不需要开发者公布所有的软件代码。有人曾经这样形象地形容API的价值, 说API好比王府井大街上的店门, 店门越多, 代表这条街上做具体生意的商家越多, 由此产生的商品品种越多样化。王府井大街对应于初始固定投入, 店家对应于边际投入;王府井大街好比系统, 店家好比应用。API是联接系统与应用的中转站, 使同一个固定资本投入可以对应多个应用上的边际投入, 使一个系统基础业务可以对应多个增值应用, 使一个基础设施可以为众多商家分享。

当前, 无论是互联网还是企业, 系统和应用越来越趋于多样化, 就算再大的公司也不可能为所有平台的所有需求编写软件。所以分离系统平台和应用, 开放系统通过API推动应用的丰富, 这是大势所趋, 尤其在环境下。专家指出, 一旦API就绪, 平台的范围经济作用就充分发挥出来。因为无论是SaaS、PaaS还是IaaS其最大特点, 就是创新和改变的成本很低, 而且创新越多, 成本越低, 增值却越大。在高度竞争中, 规模经济往往趋向降价竞争, 而范围经济往往趋向提价竞争。因此, 平台开放已不是主观上愿意不愿意的问题, 而是技术和应用形势逼迫下不得不为之的事情。

整合与配合

具体到企业信息化建设的重点——数据中心, 有一个非常重要的关键词就是“整合”, 整合网络、存储和计算, 整合硬件和软件。为了让各个独立的部分完美整合在一起, 企业必须给它们提供一种智能化的通信方式, 而不需要专业技术人员繁琐的人工干预, 开放API能够很好做到这一点。

如果设计得当, API就可以为企业做很多事情:编写软件自动迁移存储逻辑单元或虚拟机, 定义网络流的实时QoS, 给应用和服务器附加各个系统均认可的策略, 或者自己为现有产品编写自动化机制。著名科技网站TechTarget却提醒企业, 虽然开放API表面上可以解决现代数据中心网络的许多问题, 但有个前提便是企业必须知道要解决的问题是什么以及具体要实现的目标。同时, 即使企业拥有实现这种可编程性所需要的全部技术与时间, 而且所有API都开放, 那么整合数据中心内各个分散系统所需要的工作仍然很繁重。因此, 企业不仅仅需要开放API, 还需要软件和硬件设备供应商的配合, 提供所购买设备的编程访问。

企业希望不同供应商系统和设备之间能够互相通信, 比如数据中心的存储和计算系统本身知道如何连接响应网络, 告诉网络它们需要什么, 而且网络也能够与它们通信, 这就要求使用通用的协议和工具。其实在这方面, 数据中心厂商已经开始行动。阿尔卡特朗讯公司便推出了基于云计算的开发平台, 希望推动数据中心网络向更为强大的应用交付平台的转型。该开发者平台为业务提供商和企业用户提供了一系列工具, 支持合作伙伴和第三方开发者在网络上建立、测试、管理和销售各种应用。

可以适时收缩

可以说, 大多数企业已经意识到通过开放API对于重建企业商业模式上的潜力, 但并不是每个API都应该被开放, 甚至在某些情况下, 不适当的时候以不合理的形式开放API会危害到企业的API商业战略。

事实上, 企业API并不都是对外开放的, 开发者们也把这类位开放的API称为“黑色API”, 它们是被企业严格控制的。从某种程度看, 这种做法或许不符合时下 (开放) 理念, 但懂得如何在适当的时候收缩 (关闭) API对于打造成功的API商务战略来说同样重要。举个例子, 著名的线音乐网站潘多拉的IT基础架构是构建在高度依赖于API之上的, 但有意思的是该公司并没有提供公开的API。这对于一家互联网公司来看貌似是做了一个很不应该的决定, 但是试想一下, 潘多拉如果对外开放API, 虽然获得了更多的用户, 但开发者进军音乐服务领域会破坏潘多拉自己的商业模式。

A P I可以提高用户体验和改进服务质量, 如果企业期望达到这个目的, 可以考虑将API开放出来。但是如果这样做的同时会损害企业的商业模式, 这便需要CIO们做出权衡, 评估开放或者关闭API有可能带来的影响。

api应用 篇8

提供广告API吸引大客户

Twitter在向大广告客户献殷勤,很快将允许大广告客户以自动方式直接在其服务上发布大量广告。

Twitter将于今年第四季度提供广告API服务,帮助广告客户和企业发布大量的广告。在开始阶段,这项服务仅面向少数的几个合作伙伴,以测试其效果。

大型在线营销代理公司大多使用谷歌、facebook这类热门网站发布大量广告。通过向这类大型公司敞开大门,广告API服务对于Twitter尚未成熟的广告业务是一个飞跃性的进步,将有助于提升Twitter 的广告业务。

专业人士称,“这将加大广告商参与到该平台的机会,目前广告商要在Twitter上发布广告,需要和销售人员取得联系。” 他希望继续保持匿名,因为新服务的详细资料是保密的。

此举也将可能给Twitter带来消费反弹的风险。牙齿美白、减肥产品等这种极端无聊的广告轰炸式的投放,容易造成用户流失。目前,Twitter对广告已经采取循序渐进的方法,以防止用户反感。

Twitter从成立到现在,已经经历了五年的风雨。Twitter正在积极采取措施增加营收。Twitter估值在迅速上涨,外界对Twitter像LinkedIn和Groupon那样上市的预期越来越大。

目前Twitter有超过2亿的用户,但在广告方面落后于Facebook,预计Facebook今年的广告收入将达40亿美元。《纽约时报》报道称,Twitter正计划以80亿美元的估值募资4亿美元。因此,Twitter急需寻找创收的方法。

Twitter的广告新举措目前还有很多细节未确定。消息人士表示,最初,Twitter的广告API将允许广告客户以自动方式发布两种格式的广告,即Promoted Tweets(微博推广)和Promoted Account(用户推广)。

Promoted Tweets允许广告客户在用户发布的140字以内的Twitter消息中插入广告,Promoted Account则允许广告客户向Twitter用户推介自己的帐户。

Twitter是最受欢迎的互联网社交网站公司之一,它拥有超过200多万的注册用户。目前,它在广告投放力度上,仍然落后于Facebook那些规模更大的竞争对手。Facebook预计今年将产生4亿美元的广告收入。

广告界的新生儿

Twitter从2010年4月才开始提供广告服务,目前拥有大约600家广告商。据eMarketer预测,2011年Twitter的广告收入将达到1.5亿美元。

Twitter发言人马特•格拉夫斯(Matt Graves)在一封电子邮件中表示,“我们总是在考虑帮助广告客户提高广告投资回报的方法。”格拉夫斯没有就Twitter的广告API发表评论。

Twitter即将推出的广告API还可以用来开发自主广告服务。Twitter称计划于今年年底引入此服务。

Facebook和谷歌网站提供广告自助服务功能,方便小企业购买广告。广告客户只需在线填写表格就可以设置广告参数,例如在广告中显示的文字、愿意支付的价格。

Groupon、Zynga这类严重依赖网络市场的公司,他们经常需要大宗地进行广告购买。一些代表多个广告主的广告机构,他们也经常运作大型的网络广告,可能涉及成千上万个不同的广告。所以,对于这类需要大量购买广告的大广告客户来说,这类系统是不适合的。

API标准化的技术装置,使得不同的软件程序间的交流和互动成为了一种可能。提供API接口将有助于吸引大的广告营销机构,这些广告机构通常需要大量发布广告,而方式就是通过开发特定工具,直接和网站广告API相连。目前,已经有许多广告公司采用了专门的工具,可以直接连接到Facebook和谷歌广告的API。

上一篇:除夕夜作文550字下一篇:《金刚经》词语释义