重粒子的运行轨迹

Compiling ...
baryon.cpp
baryon.cpp(1) : warning C0000: all glory is fleeing
F1:Technology is worthless - even dangerous - if we don't pay attention to the human aspects of both its use and its construction
随笔 - 58, 评论 - 276, 引用 - 0

导航

关于

标签

每月存档

最新留言

  • re: C#3.0

    by 好(匿名) on 2004/10/27 19:39:00
  • re: C#3.0
    超前
    by 超前(匿名) on 2004/10/27 19:38:00
  • re: 动机与价值
    发起人,写的很好
    by 支持(匿名) on 2004/10/27 19:34:00
  • re: 动机与价值
    免费是一种运营模式,嫌钱才是目的,世界上的free是相对的!
    by 波(匿名) on 2004/10/27 19:32:00
  • re: QA
    コンポボックスですかな?わからない。宅急便さんが着たら、相談してもいいよ。
    by 重粒子(匿名) on 2004/10/22 14:58:00
  • re: QA
    連絡するとき、相手は午前中は難しいと言ってた。あとは、いくといわれました。 <br>そして自転車のコンポも必要です。コンポはどう意味ですか。聞いてもわからないです。
    by leptonw(匿名) on 2004/10/22 14:42:00
  • re: QA
    まあ、連絡したね。大丈夫はず。
    by 重粒子(匿名) on 2004/10/22 14:33:00
  • re: QA
    宅急便がもし明日、来られなかったら、困ります。
    by leptonw (匿名) on 2004/10/22 13:54:00
  • re: QA
    送り状については明日、宅急便さんが着たら、書きます
    by 重粒子(匿名) on 2004/10/22 13:29:00
  • re: QA
    削除します
    by 重粒子(匿名) on 2004/10/22 13:27:00
  • re: QA
    借りたときには言ったことがありますよ。
    by 重粒子(匿名) on 2004/10/22 13:27:00
  • re: QA
    bedの件はhuang yanにお知らせしたほうがいいですが。
    by leptonw(匿名) on 2004/10/22 13:14:00
  • re: QA
    メールとか削除しますか?
    by leptonw (匿名) on 2004/10/22 13:06:00
  • re: QA
    先ほど宅急便に連絡時、送り状とか言わなかったですが。
    by leptonw (匿名) on 2004/10/22 13:05:00
  • re: QA
    OK
    by 重粒子(匿名) on 2004/10/22 12:07:00
  • re: QA
    >吉原さんは本社と確認するって言われましたね <br>言いました。また「私から王さんに連絡します。」と言いました。でも今までまだ。私は電話するのがちょっと嫌ですから。
    by leptonw(匿名) on 2004/10/22 11:59:00
  • re: QA
    自転車は処理しませんよ。宅急便に頼みました。
    by leptonw(匿名) on 2004/10/22 11:57:00
  • re: QA
    OK。bedをごみとして処理しますね。どう2階から1階に移動するの? <br>
    by 重粒子(匿名) on 2004/10/22 11:50:00
  • re: QA
    処理します。自転車も?
    by 重粒子(匿名) on 2004/10/22 11:49:00
  • re: QA
    宅急便に頼みました。明日午前中来られますといわれました。 <br>私は自転車より大きな荷物はないと言いましたので。
    by leptonw(匿名) on 2004/10/22 11:47:00
  • re: QA
    粗大ゴミとして処理すれば、一個810円です。処理しますか?
    by leptonw(匿名) on 2004/10/22 11:45:00
  • re: QA
    困る。だめなら、値段無視してね
    by 重粒子(匿名) on 2004/10/22 10:56:00
  • re: QA
    引越しセンターでは自転車は一台、1万円以上かかるそうです。
    by leptonw(匿名) on 2004/10/22 10:49:00
  • re: QA
    だめなら、10000円引越しもあるんです。でも、電話番号わかりません。WEBだけ知ってる。 <br>メールの最後をご覧ください
    by 重粒子(匿名) on 2004/10/22 10:48:00
  • re: QA
    自転車とベッドがちょっと預かりにくいです。どうしましょうか
    by leptonw(匿名) on 2004/10/22 10:46:00

广告

【第1页/共3页,58条】
首页
前页
1
2004年09月09日

Please input your question

posted on 2004-09-09 08:54:00 by baryon  评论(46) 阅读(1449)

 
2004年08月16日

1,使用No!Flash这个软件,对是否允许网页显示Flash进行切换以后,无法使用Ctrl+N的方式打开新的IE窗口立即看到Flash或者立即屏蔽Flash。这是IE对ActiveX的显示与否作了改变。

2,新的firewall对UDP通信的防护没有原来的版本严格。我开发的一个使用了UDP通信的远程画笔软件可以毫无问题地穿过SP2的firewall。而在原来XP环境下,则根本无法这样做。我不清楚这是否是SP2的漏洞,但我觉得这样很危险。

重粒子@不要相信任何firewall

posted on 2004-08-16 15:49:00 by baryon  评论(3) 阅读(1201)

 
2004年08月10日

如果你使用VSS管理你的源程序,那么可以程序开头加上这样的注释

/*
* $Header:  $
*
* $History:  $
 *
*/
然后打开VSS的Admin管理程序,在「工具」->「选项」的第一个Page的第2个textbox处添上你的源程序的后缀,比如:*.cpp,*.h

今后的版本信息,文件名,更新时刻都会自动作为添加到你程序里了。

 $Header:  $这样的keyword有好几个,而且也不一定要放到注释里。比如VSS的Help里说可以这样用

Last modified on <!--$$JustDate:--!> <!--$-->

灵活应用这个技巧,你可以做得更好。

 

 

posted on 2004-08-10 18:01:00 by baryon  评论(1) 阅读(807)

 

1,左值,右值

我们知道对一个变量付值可以这么写

   i = 7;            // Correct. A variable name, i, is an l-value.

   //7 = i;            // C2106. A constant, 7, is an r-value.
是不对的。

也许你并不知道可以这么用

    ((i < 3) ? i : j) = 8; // Correct. Conditional operator (? :)
                          //  returns an l-value.
根据 i 的初始值不同,8要么付给 i ,要么付给 j

2,2的幂

我们知道C++里求一个数的幂可以这么做

double x = 2.0, y = 3.0, z;

 z = pow( x, y );
也许你不知道如果是求2的整数次方的话有更简单的方法

int y=3,z;

z=1<<y; //相当于(int)pow(2.0, y);

当然你要注意结果不要溢出。

3,使用移位来求一个整数的乘2的倍数,除2的倍数

这个Tip可以说很多教科书里都写了,我就不重复了。

 

posted on 2004-08-10 17:47:00 by baryon  评论(2) 阅读(809)

 
2004年07月29日

Anders Hejlsberg - Programming data in C# 3.0

http://channel9.msdn.com/ShowPost.aspx?PostID=10276

 Cω 

http://research.microsoft.com/Comega/

重粒子@你想追求最新的技术吗?那你最好自己去创造它!

posted on 2004-07-29 12:23:00 by baryon  评论(5) 阅读(933)

 
2004年07月26日

1,WTL发布了最新版本WTL75_4196 ,新版本仅仅修改了有限的几个BUG。但是加入支持Visual Studio 8.0的Wizard。

2,一个通过收集网上的WTL代码,加工修正,并且添加自创代码的基于WTL的图形界面库被创立了。网址在http://cosoft.org.cn/projects/wui/ 欢迎WTL的爱好者加入,共创共享WTL给我们带来的窗口世界。

3,一个讨论各种模板库的论坛在AllAboutProgram.com被建立了。网址: http://www.allaboutprogram.com/viewforum.php?f=46 这里将讨论std/boost/loki/atl/wtl/.....等各种模板库。AllAboutProgram.com是一些C++专家的秘密论坛,但愿我的blog不要给那里带来混乱。

posted on 2004-07-26 15:15:00 by baryon  评论(3) 阅读(993)

 
2004年07月13日

我曾经遇到无法查看MSDN的问题。经过无数次的重装MSDN,uninstall 各种软件都无效后,发现了问题所在。如果我以另外一个account登录windows,msdn的内容就可以正确了。而ms-help协议实际就是安装在自己机器里的http,也是通过IE来访问的。所以判断可能是cache有问题了。

我使用另外一个具有administrator权限的帐号登录,找到C:\Documents and Settings\<User ID>\Local Settings\Temporary Internet Files\Content.IE5 删除。回到我的account里,MSDN就完全正确了。

具体原因也许是index.dat 莫名其妙地被lock上了。也许就是也许。

posted on 2004-07-13 09:46:00 by baryon  评论(7) 阅读(1225)

 
2004年07月07日

这是我的第3篇关与native event的随笔。第一篇对native event作了简介。第二篇报告一个BUG。这一篇我们看看native event是如何实现的,并且尝试解决我们遇到的BUG。

从VC7(Microsoft Visual C++ .NET (2002) )开始MSVC提供了native event这一机制,试图为C++引入一个实现delegate的办法。一共提供了4个扩展关键子:__event (定义一个event),__raise(触发一个event),__hook(将一个成员函数连到event上),__unhook(去掉指定的函数),和两个作用在类上的特性:event_source(一个事件源),event_receiver(一个事件接受者)。

为什么会提供这么多看上去很丑陋的关键子呢?这些关键子生成了什么样的代码呢?

可以使用下面的编译命令来编译我在第二篇随笔里的代码。

cl /Fx /Fas native_event.cpp

/Fx编译选项会生成一个native_event.mrg.cpp,这是MSVC编译器对特性作了展开以后生成的源代码。/Fas编译选项生成相应的汇编代码。

我们看看native_event.mrg.cpp就足够了解native event的实现方法了。

__event关键子被展开成为一个事件函数链表指针,一个虚构造体,一个模板构造体,3个模板函数,一个名为__RemoveAllEventHandlers的成员函数,一个与event名同名的inline函数。除此以外还有4个辅助结构体。 可见event机制是非常类似宏定义的实现方案

__hook通过__AddEventHandler模板函数将函数指针追加到函数链表里。__unhook从链表中删除函数指针。

__raise本身没有什么用处。实际调用的事件函数的时候,会循环调用函数链表里的函数。函数链表的每个节点里都存储了对象实体指针(this)和成员函数指针。成员函数指针同void*指针的转换利用了__eventingGetAddr这个灵巧的辅助类。

虽然代码看上去有点乱,但并不是很长,应该很容易看懂。

我在第二篇随笔里提到的bug,发生在

??????? int __isEqual(void* p, void* pfn)
??????? {
??????????? return ((T*) p == this->p) && (__eventingGetAddr::__getMAddr(pfn) == (void ( T::*) ()) pmfn);
??????? }
这个函数里。多继承的情况下对(void ( T::*) ()) 形式的指针做比较是比较微妙的,明明相等的指针确返回了false。查看汇编代码发现一共比较了8个byte,两个DWORD PTR,具体为什么这么做我还需要做一些分析。

看上去一个可行的代替方案是:

??????? int __isEqual(void* p, void* pfn)
??????? {
??????????? return ((T*) p == this->p) && pfn == __eventingGetAddr::__getVAddr((void (T::*) ()) pmfn));
??????? }
将函数指针转换成void*,然后再做比较。从asm看到这产生了高效的代码。

这个BUG导致的后果就是:无法在ATL/WTL中使用native event。这使的这一机制几乎失去了意义。

警告:使用native event要小心。

建议:在MSVC改正BUG之前不要使用native event。

CodeProject里有一篇最近发表的文章提出一种FastDelegate方法,似乎是不错的single-target delegate 解决方案。boost的function和signals则是更加值得关注的。

posted on 2004-07-07 14:49:00 by baryon  评论(1) 阅读(875)

 

SYMPTOMS

当在一个使用多继承类作为event_receiver的未托管应用程序中unhook (__unhook) 一个native events时, 将会失败。__unhook将返回1(表明没有成功地unhook。在应用程序结束以后native event机制造成了内存泄漏.

CAUSE

这个问题发生在事件的接受者(event_receiver)是多继承类的情况下。在unhook的时候event的注入代码无法正确比较成员函数指针。

WORKAROUND

这个问题可以使用下面的代码重现:

#include

class A
{
?int a;
};

class B
{
?int b;
};

[event_source(native)]
class CSource
{
public:
?? __event void MyEvent(int nValue);
};

[event_receiver(native)]
class CReceiver : public A, public B //多继承
{
public:
?? void MyHandler1(int nValue) {
????? printf("MyHandler1 was called with value %d.\n", nValue);
?? }

?? void MyHandler2(int nValue) {
????? printf("MyHandler2 was called with value %d.\n", nValue);
?? }
};

int main() {
?? CSource source;
?? CReceiver receiver;

?? __unhook(&CSource::MyEvent, &source, &CReceiver::MyHandler2, &receiver);
?? __hook(&CSource::MyEvent, &source, &CReceiver::MyHandler1, &receiver);
?? __raise source.MyEvent(1);
?? __unhook(&CSource::MyEvent, &source, &CReceiver::MyHandler1, &receiver);//失败
?? __hook(&CSource::MyEvent, &source, &CReceiver::MyHandler2, &receiver);
?? __raise source.MyEvent(2);
?? __unhook(&CSource::MyEvent, &source, &CReceiver::MyHandler2, &receiver);//失败
?
}

运行结果

MyHandler1 was called with value 1.
MyHandler2 was called with value 2.
MyHandler1 was called with value 2.

MyHandler2没有被正确unhook。

The information in this article applies to:

  • Microsoft Visual C++ .NET (2002)
  • Microsoft Visual C++ .NET (2003)
  • Visual C++ 2005 Express Edition Beta

posted on 2004-07-07 11:10:00 by baryon  评论(0) 阅读(798)

 
2004年07月04日

1,WindowsXP的SP2已经正式进入Windows Update了,至少日文版是这样。

防火墙,放病毒等等基于安全性的考虑会对广大用户产生什么影响?

2,我遇到奇怪的MSDN内容无法显示问题已经若干个月了。在我安装最新的2004.7版本以后更是完全无法使用MSDN了。我的开发环境是Windows XP Profession SP2+VS.NET 2003。MSDN的所有页面都显示'This page cannot be displayed' ,在我以前安装的msdn版本里还能有个别页面可以显示文字。这回变的更加彻底了。而我在另外一台windows2000的机器上安装这套MSDN则完全没有问题。

我google以后还真找到了难兄难弟http://www.dotnet247.com/247reference/msgs/48/243646.aspx,

"The help wouldn't work at all, I keep getting 'This page cannot be displayed' and the error is 'Cannot find server or DNS Error Internet Explorer', so finally I re-installed MSDN for VS.NET 2003 and i still keep getting the same problem. Even clicking on 'Help on Help' was coming up with the same error"

同我遇到的症状一模一样。如有人知道原因,还望不吝赐教。

posted on 2004-07-04 00:27:00 by baryon  评论(9) 阅读(1866)

 
2004年07月01日

刚刚安装,实验了visual c++ 2005 express。

安装过程很smooth,没有遇到任何障碍,安装过程类似IE的安装,首先下载安装引导程序,执行后,他会自动下载需要的安装文件。经过一次重起以后就可以使用express了。

express没有提供atl/mfc头,只有标准库。所以只适合体验一下VC8带来的C++新特性。
我通过设置目录让express使用VS2003的atl·mfc库,发现无法编译。
因为VC8改变了一些语言规范,比如不允许在拷贝构造函数上使用摸板特例化,否则会发生Compiler Error C2299

' function ' : behavior change: an explicit specialization can not be a copy constructor or copy assignment operator

Previous versions of Visual C++ allowed explicit specializations for a copy constructor or a copy assignment operator.

The following sample generates C2299:

 Copy Code
// C2299.cpp
// compile with: /c
class C {
   template 
   C (T t);

   C (const C& );   // OK
   template <> C (const C& );   // C2299
};

在编译atlbase.h时就会得到这个错误。
看来编译windows程序还是需要下载包括包括atl/mfc的完整vs2005

经过改良的帮助系统也感觉挺舒服。

追记:对纯SDK的程序没有问题。
经过对atlbase.h等头文件的改造,又调整了若干参数,WTL提供的samples也已经被顺利编译过去了。

重粒子@本文今后也许会适当更新

posted on 2004-07-01 09:08:00 by baryon  评论(1) 阅读(1072)

 
2004年06月25日

1,mail

周日通过参加zhanbo的Quiz6,获得了一个Gmail的帐号,体验了一下充满shortcut的web mail。Gmail带来的另一个新奇就是类似news group式的mail整理方式。竞争总是带来进步。今天从日本msn上看到,hotmail开始免费250M信箱,付费用户可以获得2G的MSN Hotmail Plus增值服务。

不知道1T的信箱哪一年就会出现呢?

2,blog,goooogle

blog真是充分展示自我的舞台。年轻的与年老的,高手与菜鸟都可以尽显才华。

随之而来的信息爆炸让我感到自己的记忆力越来越差。明明记得在博客堂上看到过两次介绍一个可以帮助编写代码快速编译检验.net语法特性的小工具,昨天google了一个小时居然也没有找到。老了,不知道还能不能做程序员?

3,最近做一个C++的小项目,头一次在工作中使用了WTL和GDI+。获得好多感想和经验,回头等我慢慢道来。

posted on 2004-06-25 09:49:00 by baryon  评论(8) 阅读(1449)

 
2004年06月14日

zhanbo说他的下一个Quiz会从他的随笔里出题,我就随便翻看了一下他的一些技术随笔,第一个就看到了Perf: Conditional("DEBUG")对性能的影响 这一篇。

我想不好的编码习惯再加上使用这个了ConditionalAttribute会影响到代码的正确性。利用MSDN里的例子举例并评论如下:

using System;
using System.Diagnostics;

class Class1
{
    [STAThread]
    static void Main(string[] args)
    {               
        TextWriterTraceListener myWriter =
            new TextWriterTraceListener(System.Console.Out);
        Debug.Listeners.Add(myWriter);
        Console.WriteLine("Console.WriteLine is always displayed");
       int i=0;

        Method1(++i); //使用++i会导致不可预料的结果,因为根据不同的编译条件,这一行可能不会出现在IL里
        Method2(++i,++i);//上一行的有无会影响这一行里i的值
        //Method1("abc"); 即使根据条件这一行不会出现在IL里,也会在编译时检查参数类型。这会导致编译错误,而不是执行错误。MSDN错误地写成了type-checked at run time
    }
   
    [Conditional("CONDITION1")]
    public static void Method1(int a)
    {
        Debug.Write(String.Format("Method1 - DEBUG and CONDITION1 are specified:{0}\n", a));
        Trace.Write("Method1 - TRACE and CONDITION1 are specified\n");
    }
   
    [Conditional("CONDITION1"), Conditional("CONDITION2")]   
    public static void Method2(int a,int b)
    {
        Debug.Write(String.Format("Method2 - DEBUG, CONDITION1 or CONDITION2 are specified:{0},{1}\n", a ,b));
    }
}

D:\DOTNET>csc /target:exe /d:CONDITION2,DEBUG,TRACE /out:CASCS.exe CAS.cs

上面举例说明了,在分工合作进行开发的情况下,应该避免使用在调用函数的参数里更改变量。因为你的调用命令并不一定会被编译到最终的结果里。会发生看被调用方脸色而定的情况。我们使用 #if 或者 Debug.Write这样的命令都是可以预料结果的,而这个Attribute确让我们心神不定。

推而广之,这个Attribute使得调用方编写的任何函数调用都有可能不翼而飞。如果我写编码规范会禁止使用这个Attribute。

posted on 2004-06-14 15:20:00 by baryon  评论(3) 阅读(918)

 
2004年06月07日

根据http://www.smh.com.au/articles/2004/06/02/1086058889577.html消息,我们可以看到一个微软获得了包括Double-Click在内的关于鼠标击键动作的专利,:“一种使应用程序运行的方法,在短时间内连续击键——比如,击键两次。” (看来使用鼠标还不需要支付专利费:p)

United States Patent

6,727,830

Lui ,   et al.

April 27, 2004

Time based hardware button for application launch

posted on 2004-06-07 13:04:00 by baryon  评论(1) 阅读(919)

 
2004年05月13日
昨天,WTL的创造者Nenad Stefanovic将最新的WTL版本7.5.4133放到了SourceForge.net上。这是继Wix之后的第二个由微软贡献的开放源代码项目。
可以说MS走出这一步,真的很不容易。从2003年4月12日MS的Pranish Kumar发mail说WTL将会开放到2004年5月12日真的走出这一步,耗时13个月。

另外听说WindowsXP的盗版用户也可以安装即将推出的SP2,MS的Barry Goffe说:"It was a tough choice, but we finally decided that even if someone has pirated copy of Windows, it is more important to keep him safe than it is to be concerned about the revenue issue."

无论怎样,看上去MS变得更加灵活和开放,他们对社会的贡献度变得更大。



To: wtl@yahoogroups.com
From: "Nenad Stefanovic"
Date: Wed, 12 May 2004 15:57:08 -0700
Subject: [wtl] ANN: WTL moves to Open Source!

Hello everybody,

WTL is now available as an Open Source project on SourceForge.net. WTL
is now part of the Microsoft Shared Code initiative that enables the
community to contribute to the project.

You can find the project at http://sourceforge.net/projects/wtl.

Feel free to send your questions/comments/suggestions to me.

Cheers,
Nenad

posted on 2004-05-13 09:20:00 by baryon  评论(13) 阅读(1584)

 
2004年04月14日
在中文版.Framework SDK文档的里的"从对话框的父窗体检索信息"一节写的不清楚,英文MSDN联接在这里

原文如下:
根据对话框的用途,可能希望访问该对话框的父窗体提供的信息。对话框的初始化可能需要此信息,或者此信息可能涉及有关父窗体的应用程序状态的特定详细资料。
使用该对话框的 Form.ParentForm 属性访问父窗体的公共成员。应当将由 ParentForm 属性返回的引用显式转换成适当的类型。 下列代码演示如何使用 ParentForm 属性访问父窗体上的属性(在此示例中为 Text 属性):

' Visual Basic
Public Sub GetParentText()
Dim x as String
x = CType(Me.ParentForm, Form1).Text
End Sub

// C#
public void GetParentText()
{
string x = ((Form1)this.ParentForm).Text
}


可是所谓的父窗体指的是什么呢?
这里的ParentForm属性只有在MDI环境下的子窗口才有效,可见父窗体指的是MDI风格的父窗口。(在MSDN里这之前的章节里根本没有提到过MDI字样)
如果你是通过一个普通的ShowDialog(Me)显出出来的窗口,那么千万不要被MSDN误导,这时候的父窗口需要通过Owner属性取得。我想Owner这个属性的用途远远大与ParentForm。(为什么会弄出两个属性呢???)

读MSDN很有用。我知道了Close()并不会真正关闭窗口,只是Hide()而已。Dispose()才是生死判官。呵呵。

posted on 2004-04-14 16:59:00 by baryon  评论(2) 阅读(1041)

 
2004年04月12日

C#不支持缺省参数。只能通过重栽来实现缺省参数的需求。VB.NET和C++都支持。可是特性(attribute)确支持缺省参数。
另一方面,属性property的set里面有缺省参数value。

难道不自相矛盾吗???

posted on 2004-04-12 18:48:00 by baryon  评论(18) 阅读(1537)

 
1,使用System.IO.Path.GetFullPath(.)或者System.IO.Path.GetFullPath("c:")这样的命令,每次运行可能得到不同的结果。特别是是使用VS.NET开发时。
而且Framework1.0和1.1的运行结果也可能不一致。比如:GetFullPath("c:")「注意不是C:\」,在VS.NET 2002下经常会得到C:\Program Files\Microsoft Visual Studio .NET\Common7\IDE这样的结果,但有时也会得到C:\。
即使你将CurrentPath设成C:\也没有用。由于Path的IL内部使用经过优化或者是native的nGetFullPathHelper()函数取得FullPath,我无法分析具体的原因。MSDN上也没有给出足够的信息。
 
2,通过继承Control来定制自己的控件的时候,请注意属性初始化的位置。
方案(1) 变量声明既初始化
    Private _path As String = System.IO.Directory.GetCurrentDirectory ''初始位置
    Public Property Path() As String
        Get
            Return _path
        End Get
        Set(ByVal Value As String)
            _path = System.IO.Path.GetFullPath(Value)
        End Set
    End Property
 
方案(2)在New里初始化
    Private _path As String
    Public Property Path() As String
        Get
            Return _path
        End Get
        Set(ByVal Value As String)
            _path = System.IO.Path.GetFullPath(Value)
        End Set
    End Property
 
    Public Sub New()
        MyBase.New()
 
        Me._path = System.IO.Directory.GetCurrentDirectory ''初始位置
    End Sub
 
方案1,一般情况下不会出现问题。方案2,VS.NET的DesignMode会自动将你项目所在目录的写入Form的InitializeComponent()里。
如同,
.... ...
MyControl.Path = "C:\MyProject\TestControl"
.... ...
这样你的程序配布到其他机器上的时候,可能会出现目录不存在的错误。
 
以上代码为VB.NET。

posted on 2004-04-12 16:57:00 by baryon  评论(8) 阅读(1239)

 
2004年04月08日
不管你是否相信,BUG永远与我们同在。包括开心喜欢调侃的使用JAVA的"勇气"与"机遇"号火星探测器。
今天遇到的问题是来自.NET Framework 1.0/1.1的FileStream。

现象:
当我将一些文本内容写到软盘里的一个文件的时候,出现了IOException,磁盘容量已满。我的catch部分捕获了这个异常,但是我无论如何无法关闭已经打开的文件。结果就是在软盘里生成了一个0字节的文件,在我的程序不完全关闭的情况下,我用文件管理器无法删除它。

原因:
我发现这个异常是由Close引起的,Close方法在内部调用了Flush方法将缓冲区里的内容写到软盘里去的时候,发生了这个异常。异常发生以后,FileStream没有关闭文件句柄(HANDLE),导致文件一直被占用。即使我试图用CloseHandle来关闭文件句柄也不成功,原因是取得Handle这个属性在内部会调用Flush方法,导致异常发生。

解决办法:
1,不用.NET Framework 1.0/1.1提供的FileStream,自己封装Win32 API (太不现实了吧困惑的笑脸)
2,在write之前,先调用SetLength。SetLength这个方法会改变stream的大小,你需要预先计算一下你准备写多少字节到文件里去。如果磁盘已满,在这个方法上就会发生异常,这时候内部缓冲区里还没有内容,所以Close会正确关闭。
3,Close之前清空内部缓冲区。FileStream的设计者为了保证数据都会被写入文件,在这个类的很多地方都调用Flush来将内部缓冲区的内容写到磁盘上,而没有给用户提供直接操作这一缓冲区的方法。
只好用一些黑客手段达到目的了。
...
catch( IOException excep )
{
// 清空内部缓冲区
Type streamType = stream.GetType();
System.Reflection.FieldInfo field;
// 得到private int _writePos 的FieldInfo
field = streamType.GetField( "_writePos",BindingFlags.NonPublic | BindingFlags.Instance );
// 设置缓冲区指针的位置为0
field.SetValue( stream, (int)0 );
}
finally
{
stream.Close(); // Close 成功。
}

总结:
方法3无法保证对.NET Framework 今后的版本也有效。方法2对于很多情况不是很有效。方法1需要高超的技术水平。方法0,期待MS改进它的Framework 。

参考:
1,http://mag.autumn.org/Content.aspx?id=20040202140342(日文)
2,http://www.gdncom.jp/general/mllog/tech/techDetail.aspx?ID=215(日文)

posted on 2004-04-08 13:54:00 by baryon  评论(8) 阅读(1135)

 
2004年03月30日

几乎是在不知不觉中VC7为C++提供了native event这一扩展功能。

背景和动机:
当一个对象改变了状态,他怎么通知"关心"它的其他对象呢?
C++一直没有一个很好的机制解决这个问题。一般的作法是采用从C语言继承过来的回调函数的办法。
函数指针的定义方法
int func(int a,int b,int c);
int (*fp)(int ,int ,int) ;//fp是一个函数指针,
fp=func;

这种回调机制有几个问题
1,一个回调函数只能通知一个接受对象,无法同时通知多个接受者
2,如果没有接受对象需要单独判断
3,使用类函数做回调函数会比较麻烦,一般使用静态函数

boost::function是一套对回调函数的封装类。多少缓解了上面的几个问题。

如果是windows编程的话,可以利用另外一些机制完成这种对象之间的"通知"任务。比如消息,EventObject。但这些方式都依赖与复杂的SDK API。不是C++语言本身的功能。

总之C++其实没有一个属于自己的事件模型。

模型:
从VC7开始,MS提供了一个扩展的C++事件模型:Unified Event Model。 这个模型统一提供了一致的方法来解决在native C++(非COM) , COM, 和managed classes中的事件通知需求。

适用:
这种模型支持对象之间事件通知。支持多线城并发。支持从拥有事件类继承,也支持子类里拥有事件定义。

例子:
MSDN上提供了基本native event的例子。网址为:
http://msdn.microsoft.com/library/en-us/vccore/html/vcconEventHandlingInNativeC.asp

分析:
我们通过一个小程序看一下,native event的内部机制。这个小程序和分析结论来自http://lamoo.s53.xrea.com/diary/diary2003a.html
我对其做个小的修改。(见附件)

1,一个event占用4bytes的内存。
2,分配内存的时候一个类里定义的event会集中在类的最后集中分配。
3,按照追加(hook)事件的顺序,内存中维持一个单向链表。
4,hook事件的接受对象如果被删除(delete),不会自动被unhook。如果没有明确地unhook,下一次raise事件是,会有不可预料的错误。
5,event_source和event_receiver属性可以省略。


实做:
我在自己的一个程序中使用了native event,那是一个通过HTTP协议自动下载更新模块的类。那个类实例运行在单独的线城里,通过event将联接网络,下载的进度通知父线城,父线城是一个对话框,将收到的信息显示出来。这一切类似IE的下载对话框。也就是说事件是垮线城通知的。
如果你熟悉ATL7,那里面有一个CAtlHttpClient类,它的通知方式采用的是回调函数。而通常的作法往往是SendMessage给一个父线城的窗口句柄,通过windows的消息循环调用显示状态的函数。

课题:
我们现在面对两个问题:
1,一个hook必须对应一个unhook,这就像分配内存是一个new必须对应一个delete一样。如果忘记unhook就会发生内存泄漏。
2,任何一个接受者对象被delete以后,不会自动unhook。
所以我们有一个课题,就是对这种事件模型进行包装,制作一个包装类(wrapper class)来解决上面这两个问题。这个类应该类似auto_ptr,利用析构机制自动unhook,还要像boost::function一样支持各种各样的event函数。


参考
1,http://msdn.microsoft.com/library/en-us/vccore/html/vcconEventHandlingInNativeC.asp
2,http://lamoo.s53.xrea.com/diary/diary2003a.html
3,http://www.boost.org/doc/html/function.html

posted on 2004-03-30 16:28:00 by baryon  评论(3) 阅读(1261)

 
2004年03月26日

dev-club上有一个让开心就好FT的问题
其题目的本意是希望能够方便地调试存储过程,希望能将存储过程的执行细节用log打出来。
照我的理解
由于存储过程编译执行的,内部处理不是简单的字符串置换,是无法实时输出完整的执行细节的。
sql server内部有一个fn_get_sql函数,可以得到当前告诉锾存里的sql文,这个sql应该只是输出调用命令,而不是解析以后的存储过程内容。

如果希望在存储过程里输出一些信息到客户端以方便了解存储过程执行了那些条件分枝,可以使用PRINT命令。PRINT出来的结果,在客户端可以通过SqlException的Errors分别得到。每一行PRINT都会形成一个SqlError存储在Errors这个集合里。
但是这些信息只有发生SQL异常的时候才能得到,如何没有发生异常也得到调试信息,我不知道。

你知道吗?

JGTM'2004 [MVP]

Sure. One can use SqlConnection.InfoMessage event to get all these information. HTH. :)

谢谢JGTM

posted on 2004-03-26 17:51:00 by baryon  评论(10) 阅读(1085)

 
2004年03月11日

对于一个严格的项目来说,画面的大小,颜色,所用的字体等等细味的地方都是有要求的。
今天遇到一个恼火的问题:我用VB.NET开发了10几个winform,按照设计规约设置了form的属性,包括字体,ControlMenu和size。这些属性都可以在design模式的属性窗里指定,真是很方便的。而且我还使用了form的继承这一技巧,使这10几个form的外观都一致。今天遇到的问题是我的程序拿到另外一台机器上,打开项目,一查看我设置的属性。为什么size都不对了呢???这真是一个涉及个人名誉的严重问题。这么点小事情也做不好可不行啊。

调查开始了.....(省略若干字)

答案:
在VS是根据我的设定生成的代码里根本就没有size这个属性,只有ClientSize。MSDN上说,

窗体工作区的大小是除边框和标题栏外窗体的大小。窗体的工作区是窗体内可放置控件的区域。当执行图形操作或调整窗体上控件的大小和位置时,可以使用此属性获取正确的尺寸。若要获取整个窗体的大小,请使用 Size 属性或使用单个属性 Height 和 Width。

可是这个size是根据windows的desktop设置决定的,你的windows使用不同的theme,不同的字体大小都会影响一个form的边框大小和标题栏大小。

VS的生成程序聪明地用你指定的size减去当前的边框大小和标题栏大小,认为只需要记住clientsize就可以了。可是用户可是只能设置size啊,这样的在不同的theme下按照同一个开发约定开发出来的form大小就可能不一致。

这是一个BUG???我认为是。


重粒子@请去朝圣的MVP们转达民情。

 

posted on 2004-03-11 18:50:00 by baryon  评论(5) 阅读(998)

 
2004年03月04日

思归总是成为引导话提的先行者。
无论是理想主义也好现实主意也好,人类最基本的生存原则都是无法违背的。
小气的神的随笔"可能性 vs. 必要性"里有几句话给我留下了深刻印象:
"
人们若不是因为可能得到某种利益而行动就是因为他不得不这么做
人们看待事情的角度若不是以对自己是否有影响作为判断依据,就是以是否会对他人造成影响作为依据
人们做决定不是为了感受快乐就是为了逃避痛苦
"
编写程序使的程序员获得了快乐,这种快乐来自于人类本性。很小的孩子就知道在沙滩上建造城堡获得这种快乐,他使人有成就感,驾御心,驱动你去学习,从而获得魔术般的力量。
free的思想倡导我们将自己获得的快乐无偿地与人共享。商业的头脑则认为这不应该仅仅是快乐,而且也是财富,别人要获得它,就要做出等价交换。

我是倾向于后者的。曾经有人通过msn向我咨询一个商业系统的设计思想,那个系统每年为他们的公司创造几百上千万的利润,可是系统越来越庞大,开发人员换来换去,没有一个坚固的程序框架,意用性,扩展性都很差。那时候,我突然意识到不能无常地告诉他。针对他个人我只能告诉他去读什么书,看什么samples。针对公司,我就应该通过讲课的形式或者某种其他形式获得应有的报酬。那是一次思想的突变。个人的交流是相互学习的过程,单向的无偿请教则是培养懒惰的途径。

ms是最好的商业思想学习榜样,gates从一开始就认识到了正确的商业模式。给无数的人带来快乐的同时,自己也获得了巨大的财富。没有免费的午餐,但是有永远的谎言。linux是另外一种商业模式,而且是一种建立在谎言基础上的模式。redhat,ibm这些公司几乎是无偿地使用了无数为linux奉献过的头脑。他们遵循协议,公开source,他们是通过读懂或者会使用别人编写的代码来来获得利润。那些写code的人是没有报酬的。这是什么样的逻辑???
open source的自由风格影响ms这样的商业公司,使的他们明白商业的目的是要满足和提供给人们快乐,无论那是通过怎样的形式,获取最大的价值是不变的主题。

我们来看看ms发动mvp活动的动机是什么?
MVP往往是某个领域的专家,他们拥有自己的个人魅力和事业,对他们的关怀,免费提供各种好处,只需要很小的代价,就可以将ms的影响通过他们扩散到他们的周围去。
这种彼此愉悦的活动真是最好的商业举动。

MVP们不断帮助人的动力是什么?
是MVP的名誉?错
是他们的内心可以从帮助人这件事获得愉悦。因为这种举动证明他是有用的人,是可以影响别人的人。
倡导open source的人们其实同样是为了获得这种感觉。只不过没有一个ms这么大的公司去鼓励他们,给他们MVP这样的名号而已。

在很久以前听到"没有永远的朋友,只有永远的利益"这句话的时候,我才知道什么是社会。

重粒子@动机决定行为,行为决定价值

posted on 2004-03-04 12:00:00 by baryon  评论(33) 阅读(1223)

 
2004年02月26日

从n年前大学的毕业设计开始到现在,大大小小的软件项目做了很多。切身体会是如果一个项目不想最后演变成垃圾,重要的就是交流

我的大学毕业设计是给一个国外大公司的做的,当时自觉已是C语言高手,2周做个dos下的editor都是小case,何况有一个学期的时间去"发明"(笑)一个排序程序呢。除了验收前一天,硬盘损坏,通宵重写了部分代码以外,程序做的还算顺利。考验来自后来的code review,先是部长写了review计划书,指定参加review的人员,review的方式和目标。参加人员是同一个部门的先辈和我的同级生,5个人左右。review方式采用面对面方式(另外一种方式是回览,既将代码打印交给review人员,不讲解,由他们在自己方便的时间进行检查)。review的目标指出1000行代码应该发现的bug数目,当时的计划好像是每千行发现25个bug。
首先由我介绍这个程序用途,我的实现方案,然后一个函数一行一行的进行了讲解。其他人可以随时打断我。

...............
"这个变量有什么用途?怎么会叫这个名字?"
"这段代码是不是应该这么写......."
"这里应该有一些注释"
"哦,我发现了一个bug!"
...............

我们随时对出现的问题做讨论,有一个人负责记录我们讨论的结果,将不妥当程序的行号,原因,处理办法都记录在review报告书上。
经过两个小时的review,头冒汗声发抖,实实在在地发现很多以前想都没有想到的问题。
改正这些bug以后,感觉心里塌实了很多,对自己的程序质量有了很大的信心。

后来我也参加了其他人的document review, code review,一直到我带领项目,组织review。切实感觉review是非常好的质量保证手段同时它促进了集体技术水平的提高。
我带过一些刚毕业半年的newbie做过两个项目,没有review的话那结果将无法想像。
其中一个项目工期极其紧张,在设计好框架以后的两周里,5个pair居然没有一个能拿出可以运转的模块,计划可是2个人一组1周做出两个模块啊,当时真是急得火上房。主要是大家的思想还没有统一,对如何写出程序来还不清楚。关键时刻review发挥了重要作用。我参加了一组的coding工作,实际指导和暗示了程序的写法,随后立即进行review。通过作者们的讲解,以及大家的提问和讨论,大家清楚了程序越来是怎么编出来。以后的开发效率明显提高,10个人两个月50个模块(ASP+COM+Oracle StoreProcedure)艰苦地完成了,要知道10个人里面大部分是刚毕业半年的新手。

review不是万能的,也会导致一些问题
1,得罪人。在我指出一个同级生的bug时,他恨得要命,后来同我说,当时差点就想跑过来掐死我了(:>眨眼笑脸
2,惨不人睹。有的code实在太难看,作者有时自己都看不懂了,review根本就无法进行,代码必须重写。
3,导致时间紧张。有时工期非常紧张,如果每个人的代码全都进行面对面review的话,会延误工期,这时候就需要manager做出判断,进行回览形式的review。
4,bug是永远存在的。不能完全依赖review来找出所有的bug,review以后的测试才是主要的除错手段。

重粒子@到了写回忆录的年纪了

posted on 2004-02-26 15:22:00 by baryon  评论(8) 阅读(1126)

 
2004年02月05日
我们做SE的人需要怎样的研究学习态度?

前几天在csdn上看过这篇介绍毕业生求职的文章,感叹我不如此公。8年前刚毕业的时候不如他,8年后也不如。看来我是白学了10几年的CS了。
做SE,学CS的人需要怎样的研究学习态度?
我想至少下面这几种态度是可怕的,要不得的。
1,只知皮毛就高谈阔论(危害性:低,容易辨别)
2,知晓某一方面的知识,就自吹是这个领域的专家。(危害性:中,不容易辨别,只有项目中后期才能看出来)
3,明知自己犯了错误,确为错误找理由,说明那是正确的。(危害性:大,道德有问题)

面对某一个问题,敢明白地承认自己不懂,自己做错了都是极其令人尊重的。

今天遇到了持第3种态度的人,受了刺激,胡言乱语几句。


注:
SE=System Enginer/Software Enginer
CS=Computer Science

posted on 2004-02-05 13:49:00 by baryon  评论(3) 阅读(910)

 
【第1页/共3页,58条】
首页
前页
1

Powered by: Joycode.MVC引擎 0.5.2.0