D盘

workspace
posts - 165, comments - 53, trackbacks - 0, articles - 0
  IT博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

日历

<2025年4月>
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

常用链接

文章分类

搜索

  •  

最新评论



三、MSXML
  
     从理论上说,根据XML的格式定义,我们可以自己编写一个XML的语法分析器,但实际上微软已经给我们提供了一个XML语法解析器,即一个叫做 MSXML.DLL的动态链接库,实际上它是一个COM(Component Object Model)对象库,里面封装了进行XML解析时所需要的所 有对象。因为COM是一种以二进制格式出现的和语言无关的可重用对象,所以你可以用任何语言(比如VB,VC,DELPHI,C++ Builder甚至 是脚本语言等等)对它进行调用,在你的应用中实现对XML文档的解析。
  MSXML.DLL所包括的主要COM接口有:
  1. IXMLDOMDocument(Document接口)
DOMDocument 对象是XML DOM的基础,你可以利用它所暴露的属性和方法来浏览、查询和修改XML文档的内容和结构。DOMDocument表示了树的顶层节点,它 实现了DOM文档的所有的基本方法,并且提供了额外的成员函数来支持XSL和XSLT。它创建了一个文档对象,所有其他的对象都可以从这个文档对象中得到 和创建。
  2. IXMLDOMNode(Node接口)
  IXMLDOMNode是文档对象模型(DOM)中的基本对象,元素、属性、注释、过程指令和其他的文档组件都可以认为是IXMLDOMNode。事实上,DOMDocument对象本身也是一个IXMLDOMNode对象。
  3. IXMLDOMNodeList
  IXMLDOMNodeList实际上是一个节点(Node)对象的集合,节点的增加、删除和变化都可以在集合中立刻反映出来,可以通过"for.循环 "结构来遍历所有的节点。
  4. IXMLDOMParseError
  IXMLDOMParseError接口用来返回在解析过程中所出现的详细的信息,包括错误号、行号、字符位置和文本描述。
   在具体应用时可以用DOMDocument的Load方法来装载XML文档,用IXMLDOMNode 的selectNodes(查询的结果有多个, 得到存放搜索结果的链表)或selectSingleNode(查询的结果有一个,在有多个的情况下返回找到的第一个节点)方法进行查询,用 createNode和appendChild方法来创建节点和追加节点,用IXMLDOMElement的setAttribute和 getAttribute方法来设置和获得节点的属性。

 



此主题相关图片如下:

 

四、编程举例

 

1、目标文档:  

<book id="bk101">
       <author>lizlex</author>
       <title>XML Developer's Guide</title>
    </book>

2、步骤:

(1)在StdAfx.h中引入动态链接库 MSXML.DLL(C:\windows\system32\msxml4.dll)
#import <msxml4.dll>

(2)界面设计:
分别放入三个Text,用于输入数据,与显示文档内容用,并添加关联的成员变量m_strId,m_strAuthor, m_strTitle;并添加确定按钮:

(3)产生文档的程序片断
void CXmlparseDlg::OnButtonGenerate()
{
UpdateData();

MSXML2::IXMLDOMDocumentPtr pDoc;
MSXML2::IXMLDOMElementPtr   xmlRoot ;

     //创建DOMDocument对象
HRESULT hr = pDoc.CreateInstance(__uuidof(MSXML2::DOMDocument40));
if(!SUCCEEDED(hr))
{  
   MessageBox("无法创建DOMDocument对象,请检查是否安装了MS XML Parser 运行库!");
   return ;
}

//根节点的名称为Book
//创建元素并添加到文档中
xmlRoot=pDoc->createElement((_bstr_t)"Book");

//设置属性
xmlRoot->setAttribute("id",(const char *)m_strId);
pDoc->appendChild(xmlRoot);
MSXML2::IXMLDOMElementPtr pNode;

//添加“author”元素
pNode=pDoc->createElement((_bstr_t)"Author");
pNode->Puttext((_bstr_t)(const char *)m_strAuthor);
xmlRoot->appendChild(pNode);

//添加“Title”元素
pNode=pDoc->createElement("Title");
pNode->Puttext((const char *)m_strTitle);
xmlRoot->appendChild(pNode);

//保存到文件
//如果不存在就建立,存在就覆盖
pDoc->save("d:\\he.xml");

}

(4)读取XML文档的程序片断
void CXmlparseDlg::OnButtonLoad()
{
MSXML2::IXMLDOMDocumentPtr pDoc;
HRESULT hr;
hr=pDoc.CreateInstance(__uuidof(MSXML2::DOMDocument40));
if(FAILED(hr))
{  
   MessageBox("无法创建DOMDocument对象,请检查是否安装了MS XML Parser 运行库!");
   return ;
}

//加载文件
pDoc->load("d:\\he.xml");

MSXML2::IXMLDOMNodePtr   pNode;

//在树中查找名为Book的节点,"//"表示在任意一层查找
pNode=pDoc->selectSingleNode("//Book");

MSXML2::DOMNodeType nodeType;

//得到节点类型
     pNode->get_nodeType(&nodeType);

//节点名称
CString strName;

strName=(char *)pNode->GetnodeName();

//节点属性,放在链表中
MSXML2::IXMLDOMNamedNodeMapPtr pAttrMap=NULL;
MSXML2::IXMLDOMNodePtr    pAttrItem;
_variant_t variantvalue;
pNode->get_attributes(&pAttrMap);

long count;
count=pAttrMap->get_length(&count);

pAttrMap->get_item(0,&pAttrItem);
//取得节点的值
pAttrItem->get_nodeTypedvalue(&variantvalue);
m_strId=(char *)(_bstr_t)variantvalue;

UpdateData(FALSE);

}

此主题相关图片如下:

posted @ 2009-03-13 15:56 巴西木 阅读(1322) | 评论 (0)编辑 收藏

另可参考:
[转]DEBUG和RELEASE版本差异及调试相关问题

Debug和Release有什么区别?怎么把Debug转成Release ?
1。Debug和Release有什么区别,为什么要使用Release版本!  
2。怎么把Debug转成Release  

转载:  

Debug版本包括调试信息,所以要比Release版本大很多(可能大数百K至数M)。至于是否需要DLL支持,主要看你采用的编译选项。如果是基于ATL的,则Debug和Release版本对DLL的要求差不多。如果采用的编译选项为使用MFC动态库,则需要MFC42D.DLL等库支持,而Release版本需要MFC42.DLL支持。Release   Build不对源代码进行调试,不考虑MFC的诊断宏,使用的是MFC   Release库,编译十对应用程序的速度进行优化,而Debug   Build则正好相反,它允许对源代码进行调试,可以定义和使用MFC的诊断宏,采用MFC   Debug库,对速度没有优化。    


一、Debug   和   Release   编译方式的本质区别  

Debug   通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。Release   称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。  
Debug   和   Release   的真正秘密,在于一组编译选项。下面列出了分别针对二者的选项(当然除此之外还有其他一些,如/Fd   /Fo,但区别并不重要,通常他们也不会引起   Release   版错误,在此不讨论)  

Debug   版本:  
/MDd   /MLd   或   /MTd   使用   Debug   runtime   library(调试版本的运行时刻函数库)  
/Od   关闭优化开关  
/D   "_DEBUG"   相当于   #define   _DEBUG,打开编译调试代码开关(主要针对  
assert函数)  
/ZI   创建   Edit   and   continue(编辑继续)数据库,这样在调试过  
程中如果修改了源代码不需重新编译  
/GZ   可以帮助捕获内存错误  
/Gm   打开最小化重链接开关,减少链接时间  

Release   版本:    
/MD   /ML   或   /MT   使用发布版本的运行时刻函数库  
/O1   或   /O2   优化开关,使程序最小或最快  
/D   "NDEBUG"   关闭条件编译调试代码开关(即不编译assert函数)  
/GF   合并重复的字符串,并将字符串常量放到只读内存,防止  
被修改  

实际上,Debug   和   Release   并没有本质的界限,他们只是一组编译选项的集合,编译器只是按照预定的选项行动。事实上,我们甚至可以修改这些选项,从而得到优化过的调试版本或是带跟踪语句的发布版本。  

二、哪些情况下   Release   版会出错  

有了上面的介绍,我们再来逐个对照这些选项看看   Release   版错误是怎样产生的  

1.   Runtime   Library:链接哪种运行时刻函数库通常只对程序的性能产生影响。调试版本的   Runtime   Library   包含了调试信息,并采用了一些保护机制以帮助发现错误,因此性能不如发布版本。编译器提供的   Runtime   Library   通常很稳定,不会造成   Release   版错误;倒是由于   Debug   的   Runtime   Library   加强了对错误的检测,如堆内存分配,有时会出现   Debug   有错但   Release   正常的现象。应当指出的是,如果   Debug   有错,即使   Release   正常,程序肯定是有   Bug   的,只不过可能是   Release   版的某次运行没有表现出来而已。  

2.   优化:这是造成错误的主要原因,因为关闭优化时源程序基本上是直接翻译的,而打开优化后编译器会作出一系列假设。这类错误主要有以下几种:  

(1)   帧指针(Frame   Pointer)省略(简称   FPO   ):在函数调用过程中,所有调用信息(返回地址、参数)以及自动变量都是放在栈中的。若函数的声明与实现不同(参数、返回值、调用方式),就会产生错误————但   Debug   方式下,栈的访问通过   EBP   寄存器保存的地址实现,如果没有发生数组越界之类的错误(或是越界“不多”),函数通常能正常执行;Release   方式下,优化会省略   EBP   栈基址指针,这样通过一个全局指针访问栈就会造成返回地址错误是程序崩溃。C++   的强类型特性能检查出大多数这样的错误,但如果用了强制类型转换,就不行了。你可以在   Release   版本中强制加入   /Oy-   编译选项来关掉帧指针省略,以确定是否此类错误。此类错误通常有:  

●   MFC   消息响应函数书写错误。正确的应为  
afx_msg   LRESULT   OnMessageOwn(WPARAM   wparam,   LPARAM   lparam);  
ON_MESSAGE   宏包含强制类型转换。防止这种错误的方法之一是重定义   ON_MESSAGE   宏,把下列代码加到   stdafx.h   中(在#include   "afxwin.h"之后),函数原形错误时编译会报错  
#undef   ON_MESSAGE  
#define   ON_MESSAGE(message,   memberFxn)   \  
{   message,   0,   0,   0,   AfxSig_lwl,   \  
(AFX_PMSG)(AFX_PMSGW)(static_cast<   LRESULT   (AFX_MSG_CALL   \  
CWnd::*)(WPARAM,   LPARAM)   >   (&memberFxn)   },  

(2)   volatile   型变量:volatile   告诉编译器该变量可能被程序之外的未知方式修改(如系统、其他进程和线程)。优化程序为了使程序性能提高,常把一些变量放在寄存器中(类似于   register   关键字),而其他进程只能对该变量所在的内存进行修改,而寄存器中的值没变。如果你的程序是多线程的,或者你发现某个变量的值与预期的不符而你确信已正确的设置了,则很可能遇到这样的问题。这种错误有时会表现为程序在最快优化出错而最小优化正常。把你认为可疑的变量加上   volatile   试试。  

(3)   变量优化:优化程序会根据变量的使用情况优化变量。例如,函数中有一个未被使用的变量,在   Debug   版中它有可能掩盖一个数组越界,而在   Release   版中,这个变量很可能被优化调,此时数组越界会破坏栈中有用的数据。当然,实际的情况会比这复杂得多。与此有关的错误有:  
●   非法访问,包括数组越界、指针错误等。例如  
void   fn(void)  
{  
int   i;  
i   =   1;  
int   a[4];  
{  
int   j;  
j   =   1;  
}  
a[-1]   =   1;//当然错误不会这么明显,例如下标是变量  
a[4]   =   1;  
}  
j   虽然在数组越界时已出了作用域,但其空间并未收回,因而   i   和   j   就会掩盖越界。而   Release   版由于   i、j   并未其很大作用可能会被优化掉,从而使栈被破坏。  

3.   _DEBUG   与   NDEBUG   :当定义了   _DEBUG   时,assert()   函数会被编译,而   NDEBUG   时不被编译。除此之外,VC++中还有一系列断言宏。这包括:  

ANSI   C   断言   void   assert(int   expression   );  
C   Runtime   Lib   断言   _ASSERT(   booleanExpression   );  
_ASSERTE(   booleanExpression   );  
MFC   断言   ASSERT(   booleanExpression   );  
VERIFY(   booleanExpression   );  
ASSERT_VALID(   pObject   );  
ASSERT_KINDOF(   classname,   pobject   );  
ATL   断言   ATLASSERT(   booleanExpression   );  
此外,TRACE()   宏的编译也受   _DEBUG   控制。  

所有这些断言都只在   Debug版中才被编译,而在   Release   版中被忽略。唯一的例外是   VERIFY()   。事实上,这些宏都是调用了   assert()   函数,只不过附加了一些与库有关的调试代码。如果你在这些宏中加入了任何程序代码,而不只是布尔表达式(例如赋值、能改变变量值的函数调用   等),那么   Release   版都不会执行这些操作,从而造成错误。初学者很容易犯这类错误,查找的方法也很简单,因为这些宏都已在上面列出,只要利用   VC++   的   Find   in   Files   功能在工程所有文件中找到用这些宏的地方再一一检查即可。另外,有些高手可能还会加入   #ifdef   _DEBUG   之类的条件编译,也要注意一下。  
顺便值得一提的是   VERIFY()   宏,这个宏允许你将程序代码放在布尔表达式里。这个宏通常用来检查   Windows   API   的返回值。有些人可能为这个原因而滥用   VERIFY()   ,事实上这是危险的,因为   VERIFY()   违反了断言的思想,不能使程序代码和调试代码完全分离,最终可能会带来很多麻烦。因此,专家们建议尽量少用这个宏。  

4.   /GZ   选项:这个选项会做以下这些事  

(1)   初始化内存和变量。包括用   0xCC   初始化所有自动变量,0xCD   (   Cleared   Data   )   初始化堆中分配的内存(即动态分配的内存,例如   new   ),0xDD   (   Dead   Data   )   填充已被释放的堆内存(例如   delete   ),0xFD(   deFencde   Data   )   初始化受保护的内存(debug   版在动态分配内存的前后加入保护内存以防止越界访问),其中括号中的词是微软建议的助记词。这样做的好处是这些值都很大,作为指针是不可能的(而且   32   位系统中指针很少是奇数值,在有些系统中奇数的指针会产生运行时错误),作为数值也很少遇到,而且这些值也很容易辨认,因此这很有利于在   Debug   版中发现   Release   版才会遇到的错误。要特别注意的是,很多人认为编译器会用   0   来初始化变量,这是错误的(而且这样很不利于查找错误)。  
(2)   通过函数指针调用函数时,会通过检查栈指针验证函数调用的匹配性。(防止原形不匹配)  
(3)   函数返回前检查栈指针,确认未被修改。(防止越界访问和原形不匹配,与第二项合在一起可大致模拟帧指针省略   FPO   )  

通常   /GZ   选项会造成   Debug   版出错而   Release   版正常的现象,因为   Release   版中未初始化的变量是随机的,这有可能使指针指向一个有效地址而掩盖了非法访问。  

除此之外,/Gm   /GF   等选项造成错误的情况比较少,而且他们的效果显而易见,比较容易发现。  
--------------------------------------------------------------  
Release是发行版本,比Debug版本有一些优化,文件比Debug文件小  
Debug是调试版本,包括的程序信息更多  
Release方法:  
build->batch   build->build就OK.  

-----------------------------------------------------  

一、"Debug是调试版本,包括的程序信息更多"  

补充:只有DEBUG版的程序才能设置断点、单步执行、使用TRACE/ASSERT等调试输出语句。REALEASE不包含任何调试信息,所以体积小、运行速度快。  

二、一般发布release的方法除了hzh_shat(水)   所说的之外,还可以project->Set   Active   Config,选中release版本。此后,按F5或F7编译所得的结果就是release版本。


Trackback: http://tb.donews.net/TrackBack.aspx?PostId=131016

----------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------
VC下关于debug和release的不同的讨论
在使用VC开发软件的过程中,正当要享受那种兴奋的时候突然发现:release与debug运行结果不一致,甚至出错,而release又不方便调试,真的是当头一棒啊,可是疼归疼,问题总要解决,下面将讲述一下我的几点经验,看看是不是其中之一:

1. 变量。
大家都知道,debug跟release在初始化变量时所做的操作是不同的,debug是将每个字节位都赋成0xcc(注1),而release的赋值近似于随机(我想是直接从内存中分配的,没有初始化过)。这样就明确了,如果你的程序中的某个变量没被初始化就被引用,就很有可能出现异常:用作控制变量将导致流程导向不一致;用作数组下标将会使程序崩溃;更加可能是造成其他变量的不准确而引起其他的错误。所以在声明变量后马上对其初始化一个默认的值是最简单有效的办法,否则项目大了你找都没地方找。代码存在错误在debug方式下可能会忽略而不被察觉到,如debug方式下数组越界也大多不会出错,在release中就暴露出来了,这个找起来就比较难了:( 还是自己多加注意吧

2. 自定义消息的消息参数。
MFC为我们提供了很好的消息机制,更增加了自定义消息,好处我就不用多说了。这也存在debug跟release的问题吗?答案是肯定的。在自定义消息的函数体声明时,时常会看到这样的写法:afx_msg LRESULT OnMessageOwn(); Debug情况下一般不会有任何问题,而当你在Release下且多线程或进程间使用了消息传递时就会导致无效句柄之类的错误。导致这个错误直接原因是消息体的参数没有添加,即应该写成:afx_msg LRESULT OnMessageOwn(WPARAM wparam, LPARAM lparam); (注2)

3. release模式下不出错,但debug模式下报错。
这种情况下大多也是因为代码书写不正确引起的,查看MFC的源码,可以发现好多ASSERT的语句(断言),这个宏只是在debug模式下才有效,那么就清楚了,release版不报错是忽略了错误而不是没有错误,这可能存在很大的隐患,因为是Debug模式下,比较方便调试,好好的检查自己的代码,再此就不多说了。

4. ASSERT, VERIFY, TRACE……….调试宏
这种情况很容易解释。举个例子:请在VC下输入ASSERT然后选中按F12跳到宏定义的地方,这里你就能够发现Debug中ASSERT要执行AfxAssertFailedLine,而Release下的宏定义却为”#define ASSERT(f) ((void)0)”。所以注意在这些调试宏的语句不要用程序相关变量如i++写操作的语句。VERIFY是个例外,”#define VERIFY(f) ((void)(f))”,即执行,这里的作用就不多追究了,有兴趣可自己研究:)。

总结:
Debug与Release不同的问题在刚开始编写代码时会经常发生,99%是因为你的代码书写错误而导致的,所以不要动不动就说系统问题或编译器问题,努力找找自己的原因才是根本。我从前就常常遇到这情况,经历过一次次的教训后我就开始注意了,现在我所写过的代码我已经好久没遇到这种问题了。下面是几个避免的方面,即使没有这种问题也应注意一下:

1. 注意变量的初始化,尤其是指针变量,数组变量的初始化(很大的情况下另作考虑了)。
2. 自定义消息及其他声明的标准写法
3. 使用调试宏时使用后最好注释掉
4. 尽量使用try - catch(…)
5. 尽量使用模块,不但表达清楚而且方便调试。
注1:
afc(afc) 网友提供:
debug版初始化成0xcc是因为0xcc在x86下是一条int 3单步中断指令,这样程序如果跑飞了遇到0xcc就会停下来,这和单片机编程时一般将没用的代码空间填入jmp 0000语句是一样地
注2:
不知大家有没有遇到过这种情况,具体原因我也不太清楚,是不是调用时按着默认的参数多分配了WPARAM+LPARAM的空间而破坏了应用程序的内存空间?还请高手来补充。
NightWolf 网友提供:我遇见过,好像是在函数调用的时候参数入栈的问题。因为MFC的消息使用宏写的,所以如果定义了OnMessage()的函数,编译能够通过,但是调用一次后,堆栈指针发生了偏移。然后就。。。
------------------------------------------------------------
_________________________________________________________
---------------------------------------------------------




[转]DEBUG和RELEASE版本差异及调试相关问题
I. 内存分配问题

1. 变量未初始化。下面的程序在debug中运行的很好。

thing * search(thing * something)
BOOL found;
for(int i = 0; i < whatever.GetSize(); i++)
{
if(whatever[i]->field == something->field)
{ /* found it */
found = TRUE;
break;
} /* found it */
}
if(found)
return whatever[i];
else
return NULL;
而在release中却不行,因为debug中会自动给变量初始化found=FALSE,而在release版中则不会。所以尽可能的给变量、类或结构初始化。

2. 数据溢出的问题

如:char buffer[10];
int counter;

lstrcpy(buffer, "abcdefghik");

在debug版中buffer的NULL覆盖了counter的高位,但是除非counter>16M,什么问题也没有。但是在release版中,counter可能被放在寄存器中,这样NULL就覆盖了buffer下面的空间,可能就是函数的返回地址,这将导致ACCESS ERROR。

3. DEBUG版和RELEASE版的内存分配方式是不同的 。如果你在DEBUG版中申请 ele 为 6*sizeof(DWORD)=24bytes,实际上分配给你的是32bytes(debug版以32bytes为单位分配), 而在release版,分配给你的就是24bytes(release版以8bytes为单位),所以在debug版中如果你写ele[6],可能不会有什么问题,而在release版中,就有ACCESS VIOLATE。

II. ASSERT和VERIFY

1. ASSERT在Release版本中是不会被编译的。

ASSERT宏是这样定义的

#ifdef _DEBUG
#define ASSERT(x) if( (x) == 0) report_assert_failure()
#else
#define ASSERT(x)
#endif
实际上复杂一些,但无关紧要。假如你在这些语句中加了程序中必须要有的代码
比如

ASSERT(pNewObj = new CMyClass);

pNewObj->MyFunction();

这种时候Release版本中的pNewObj不会分配到空间

所以执行到下一个语句的时候程序会报该程序执行了非法操作的错误。这时可以用VERIFY :

#ifdef _DEBUG
#define VERIFY(x) if( (x) == 0) report_assert_failure()
#else
#define VERIFY(x) (x)
#endif
这样的话,代码在release版中就可以执行了。

III. 参数问题:

自定义消息的处理函数,必须定义如下:

afx_msg LRESULT OnMyMessage(WPARAM, LPARAM);

返回值必须是HRESULT型,否则Debug会过,而Release出错

IV. 内存分配

保证数据创建和清除的统一性:如果一个DLL提供一个能够创建数据的函数,那么这个DLL同时应该提供一个函数销毁这些数据。数据的创建和清除应该在同一个层次上。

V. DLL的灾难

人们将不同版本DLL混合造成的不一致性形象的称为 “动态连接库的地狱“(DLL Hell) ,甚至微软自己也这么说http://msdn.microsoft.com/library/techart/dlldanger1.htm)。

如果你的程序使用你自己的DLL时请注意:

1. 不能将debug和release版的DLL混合在一起使用。debug都是debug版,release版都是release版。

解决办法是将debug和release的程序分别放在主程序的debug和release目录下


2. 千万不要以为静态连接库会解决问题,那只会使情况更糟糕。

VI. RELEASE板中的调试 :

1. 将ASSERT() 改为 VERIFY() 。找出定义在"#ifdef _DEBUG"中的代码,如果在RELEASE版本中需要这些代码请将他们移到定义外。查找TRACE(...)中代码,因为这些代码在RELEASE中也不被编译。 请认真检查那些在RELEASE中需要的代码是否并没有被便宜。

2. 变量的初始化所带来的不同,在不同的系统,或是在DEBUG/RELEASE版本间都存在这样的差异,所以请对变量进行初始化。

3. 是否在编译时已经有了警告?请将警告级别设置为3或4,然后保证在编译时没有警告出现.

VII. 将Project Settings" 中 "C++/C " 项目下优化选项改为Disbale(Debug)。编译器的优化可能导致许多意想不到的错误,请参http://www.pgh.net/~newcomer/debug_release.htm

1. 此外对RELEASE版本的软件也可以进行调试,请做如下改动:

在"Project Settings" 中 "C++/C " 项目下设置 "category" 为 "General" 并且将"Debug Info"设置为 "Program Database"。

在"Link"项目下选中"Generate Debug Info"检查框。

"Rebuild All"

如此做法会产生的一些限制:

无法获得在MFC DLL中的变量的值。

必须对该软件所使用的所有DLL工程都进行改动。

另:

MS BUG:MS的一份技术文档中表明,在VC5中对于DLL的"Maximize Speed"优化选项并未被完全支持,因此这将会引起内存错误并导致程序崩溃。

2. http://www.sysinternals.com/有一个程序DebugView,用来捕捉OutputDebugString的输出,运行起来后(估计是自设为system debugger)就可以观看所有程序的OutputDebugString的输出。此后,你可以脱离VC来运行你的程序并观看调试信息。

3. 有一个叫Gimpel Lint的静态代码检查工具,据说比较好用http://www.gimpel.com/ 不过要化$的。

参考文献:

1) http://www.cygnus-software.com/papers/release_debugging.html

2) http://www.pgh.net/~newcomer/debug_release.htm

posted @ 2009-03-13 15:11 巴西木 阅读(281) | 评论 (0)编辑 收藏

为了能用上原来的C++代码,只好研究下从C# 中调用DLL
首先必须要有一个声明,使用的是DllImport关键字:
包含DllImport所在的名字空间
using System.Runtime.InteropServices;
public class XXXX{

[DllImport(“MyDLL.dll")]
public static extern int mySum (int a,int b);
}


[DllImport(“MyDLL.dll")]
public static extern int mySum (int a,int b);
代码中DllImport关键字作用是告诉编译器入口点在哪里,并将打包函数捆绑在这个类中
在调用的时候
在类中的时候 直接   mySum(a,b);就可以了
在其他类中调用: XXXX. mySum(a,b);

[DllImport(“MyDLL.dll”)]在申明的时候还可以添加几个属性
[DllImport(“MyDLL.dll", EntryPoint=" mySum ",CharSet=CharSet.Auto,CallingConvention=CallingC
文件: PInvoke.rar
大小: 2790KB
下载: 下载
onvention.StdCall)
]
EntryPoint: 指定要调用的 DLL 入口点。默认入口点名称是托管方法的名称 。
CharSet: 控制名称重整和封送 String 参数的方式 (默认是UNICODE)
CallingConvention指示入口点的函数调用约定(默认WINAPI)(上次报告讲过的)
SetLastError 指示被调用方在从属性化方法返回之前是否调用 SetLastError Win32 API 函数 (C#中默认false )


int 类型
[DllImport(“MyDLL.dll")]
//返回个int 类型
public static extern int mySum (int a1,int b1);
//DLL中申明
extern “C” __declspec(dllexport)  int WINAPI mySum(int a2,int b2)
{
//a2 b2不能改变a1 b1
//a2=..
//b2=...
return a+b;
}


//参数传递int 类型
public static extern int mySum (ref int a1,ref int b1);
//DLL中申明
extern “C” __declspec(dllexport)  int WINAPI mySum(int *a2,int *b2)
{
//可以改变 a1, b1
*a2=...
*b2=...
return a+b;
}


DLL 需传入char *类型
[DllImport(“MyDLL.dll")]
//传入值
public static extern int mySum (string  astr1,string bstr1);
//DLL中申明
extern “C” __declspec(dllexport)  int WINAPI mySum(char * astr2,char * bstr2)
{
//改变astr2 bstr 2  ,astr1 bstr1不会被改变
return a+b;
}


DLL 需传出char *类型
[DllImport(“MyDLL.dll")]
// 传出值
public static extern int mySum (StringBuilder abuf, StringBuilder bbuf );
//DLL中申明
extern “C” __declspec(dllexport)  int WINAPI mySum(char * astr,char * bstr)
{
//传出char * 改变astr bstr -->abuf, bbuf可以被改变
return a+b;
}

DLL 回调函数

BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam)



using System;
using System.Runtime.InteropServices;
public delegate bool CallBack(int hwnd, int lParam); //定义委托函数类型
public class EnumReportApp
{
[DllImport("user32")]
public static extern int EnumWindows(CallBack x, int y);
public static void Main() {
CallBack myCallBack = new CallBack(EnumReportApp.Report); EnumWindows(myCallBack, 0);
}
public static bool Report(int hwnd, int lParam)
{
Console.Write("Window handle is ");
Console.WriteLine(hwnd); return true;
}
}


DLL  传递结构   (见代码)
BOOL PtInRect(const RECT *lprc, POINT pt);

using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
public struct Point {
public int x;
public int y;
}
[StructLayout(LayoutKind.Explicit)]
public struct Rect
{
[FieldOffset(0)] public int left;
[FieldOffset(4)] public int top;
[FieldOffset(8)] public int right;
[FieldOffset(12)] public int bottom;
}
Class XXXX {
[DllImport("User32.dll")]
public static extern bool PtInRect(ref  Rect r, Point p);
}

DLL 回调函数,传递结构 想看的msdn里面都有专题介绍,看的我都是晕晕的:)

其他参考请搜索:

在C#程序设计中使用Win32类库
C#中调用C++托管Dll
如何在C#中加载自己编写的动态链接库

相关文章:Creating a P/Invoke Library

能用上DLL以后感觉还是很好的,原来的C++代码只要修改编译通过就可以了,
高兴没多久,发现.net2005居然可以用VB,VC开发智能设备项目,可以创建MFC智能设备项目
晕晕,难道可以直接用MFC来开发smartphone的程序了,赶紧看看,,,

posted @ 2009-03-10 15:03 巴西木 阅读(702) | 评论 (0)编辑 收藏

     摘要: 早看到这篇文章好多问题都不是问题了http://jamesq.bokee.com/1263981.html oracle的sys用户怎么通过jdbc连接 经过GOOGLE 总算知道了如何在JDBC中使用SYSDBA角色连接ORACLE数据库 在DriverManager.getConnection通过Properties 设置连接的defaultRowPrefetch,nternal_log...  阅读全文

posted @ 2009-02-20 17:10 巴西木 阅读(2290) | 评论 (0)编辑 收藏

【简 介】
在设计网络应用时,您必须决定如何编辑字体。使用CSS时存在大量选项,每个开发者都有自己的喜好。本文主要讨论字体大小和网络应用内的操作。在开发网络应用时,没有比外观更重要的事情了。所以,如果发现设计人员十分关注字体及字体大小,我不会感到奇怪!

  在设计网络应用时,您必须决定如何编辑字体。使用CSS时存在大量选项,每个开发者都有自己的喜好。本文主要讨论字体大小和网络应用内的操作。在开发网络应用时,没有比外观更重要的事情了。所以,如果发现设计人员十分关注字体及字体大小,我不会感到奇怪!

  字体大小

  CSS2规范根据长度——水平和垂直尺寸——来定义字体。这个长度为一个数值,前面可能带一个可选的加(+)或减(-)标记符。另外,该数值后可能有一个可选的单位标识符。
  另外,CSS2规范定义了两个单位类型:绝对单位和相对单位。绝对值指定单位,而相对单位指定一个与另一个值成比例的值。下面的列表列出了相对单位标识符:

  em:元素字体的高度。它与使用该字体的元素的字体大小属性计算值相等。当它出现在字体大小属性值本身中时,会出现异常,这时它指母元素的字体大小。


  ex(x-高度):CSS2规范将它描述为小写字母x的高度。

  px(像素):它与背景或屏幕的分辨率有关。根据显示器分辨率输出不同像素,由于用户的喜好不同,显示器的分辨率可能会有很大差异。

  下面是有效的绝对单位标识符:


  in(英寸)
  cm(厘米)
  mm(毫米)
  pt(点,1点=1/72英寸)
  pc(12点活字,1pc=12点)

  测量绝对大小的另一种方法是使用衡量一个值的比例因数,应用以下关键字:最小、较小、小、中、大、较大和最小。中为基值,变小就减去一个因数,变大就增加一个因数,等等。CSS2规范定义的比例因数为1.2,这个值也可能依浏览器而变化。

  还可以应用百分比值来格式化文本。百分比值是一个可选的标记符,即数字后带有一个百分比符号(%)。百分比值总是与另一个值成比例。就字体而言,它与网页的基本字体大小成一定比例。

  如您所见,有许多方法可完成呈现文本这个看似简单的任务。下面的HTML格式文本(在段落元素中)应用了各种单位标识符。其中所有的值都相等,并假定以72dpi进行显示。

<html>
<head>
<title>Font Sizing - equal values</title>
</head>
<body>
<p style="font-size: 36pt;">Point</p>
<p style="font-size: 3pc;">Pica</p>
<p style="font-size: 0.5in;">Inches</p>
<p style="font-size: 1.27cm;">Centimeters</p>
<p style="font-size: 12.7mm;">Millimeters</p>
<p style="font-size: 300%;">Percentage</p>
</body>
</html>

  您可以在这个列表中增加像素值,但它的值要依环境而定。例如,我的分辨率为1280X1024的手提电脑将显示与在上表中使用50像素值一致的文本。

  仔细阅读前面提到的CSS2规范,可以获得更多字体大小方面的知识。现在我将讨论如何决定在网络应用中使用哪种方法。

  选择哪一种方法

  在CSS中有许多和字体有关的选项,但哪一种最适合在您的网络应用中使用呢?绝对大小有许多缺陷,特别是在一致性、灵活性与访问性方面存在问题。与绝对字体大小相比,任何视力有缺陷的用户可使用相对字体大小来扩大页面中的文字,这样更便于阅读。因此,开发者经常使用相对大小。

  让我们来详细了解一下相对大小:

  像素是最通用的大小值。多数浏览器都支持它,但也并非总是如此。浏览器常常将像素当作屏幕像素而非CSS像素来处理。像素的一个缺点在于,它忽略或否定用户的喜好,且不能在IE中调整大小。

  许多开发者偏爱用点来衡量字体大小,但点主要用于桌面印刷系统,不方便移植到网络中。在呈现文本时,操作系统或浏览器默认使用像素。

  最常用的方法是使用em或百分比大小。EM可在所有支持调整尺寸的浏览器中进行调整。Em还与用户偏爱的默认大小有关。在IE中应用em的结果难以预料。在IE中最好使用百分比来设定文本大小。

  下面的例子结合使用em和百分比值来对文本进行格式化。基本文本用百分比值来设置,然后用em来进行调整。

<html>
<head>
<title>Display Test</title>
<style type="text/css">
body {font: Sans Serif, Arial; font-size: 110 %}
</style></head><body>
<p style="font-size: 1.0em;">Basic text.</p>
<p style="font-size: 1.5em;">Larger text.</p>
<p style="font-size: 0.5em;">smaller text.</p>
</body>
</html>

  全都与外观有关

  现有的标准提供许多格式化并呈现网络应用中的文本的方法。开发者可以很方便地将文本分解成相对和绝对标识符。关键在于保持一致,并彻底检测解决方案

posted @ 2009-02-16 17:28 巴西木 阅读(162) | 评论 (0)编辑 收藏

仅列出标题
共33页: First 3 4 5 6 7 8 9 10 11 Last