博文

USB驱动基础(2006-05-16 15:07:00)

摘要:DriverWorks supports development of drivers that are USB clients, i.e., drivers that need to send requests over a USB to some device. From the client driver's perspective, any USB device is conceptually comprised of three classes of components: Logical Device. This is the logical component with which the USB bus driver communicates in order to configure and control the device. It corresponds to the default control pipe or "endpoint 0" as described in the USB specification. All USB devices support a common set of functions accessible via commands to the Logical Device layer of the USB protocol stack. These functions include access to the device descriptor and setting the configuration. Class KUsbLowerDevice abstracts this functionality. By instancing this class, a device driver creates an interface to the upper edge of the system USB bus driver. Interfaces. All USB devices have one or more interfaces. An interface is a grouping of the device's endpoints which provides a part......

阅读全文(3228) | 评论:0

自己想的问题(2006-03-21 14:08:00)

摘要:假设有一张白纸,单面可以写n个字,并且两面都可以写字。 现在提出下面要求: 1、只能在空白的地方写字。 2、只能在向上的那一面上写字。 3、一面写完后,可以通过折叠使没有写字的那一面部分向上。 4、挨着桌子的那一面永远不能有字。 最后,请问这张纸最多可以写多少个字?......

阅读全文(3202) | 评论:2

一个关于继承和虚函数的问题(2005-12-23 11:53:00)

摘要:首先,看一下这几行简单的代码: class  A { int  a; public: A(int aa):a(aa){}; void funa(){ a++;}; }; class B:public A { int b; public: B(int aa,int bb):A(aa),b(bb){}; virtual void funb()=0;//pure virtual function }; class C { int c; public: C(int cc):c(cc){}; virtual void func()=0; }; A a(1);//应该正确 C c(1);//应该错误 B  b(1,2);//对不对呢? 在C++语言中,拥有纯虚函数的类成为抽象类,该类不能实例化一个对象,必须在进一步继承中实现该函数,然后用派生类定义对象。那么,现在的问题是,基类为非抽象类,从他继承来的类是不是非抽象类呢?如果该继承类有纯虚函数,又属于抽象类还是非抽象类呢?还是先测试一下上面代码,看看结果: 第一次测试:(使用VC++6.0) int main(int argc, char* argv[])
{
 A a(1);
 C c(1);
 B b(1,2);
} 看看结果: F:\work2000\ddd\ddd.cpp(29) : error C2259: 'C' : cannot instantiate abstract class due to following members:
        F:\work2000\ddd\ddd.cpp(20) : see declaration of 'C'
F:\work2000\ddd\ddd.cpp(29) : warning C4259: 'void __thiscall C::func(void)' : pure virtual function was not defined
        F:\work2......

阅读全文(11325) | 评论:2

Pointers, handles, and null(2005-12-14 15:25:00)

摘要:Standard C++ supports pointer types and null pointer constants. C++/CLI adds handle types and null values. 20
To help integrate handles, and to have a universal null, C++/CLI defines the keyword nullptr. This 21
keyword represents a literal having the null type. nullptr is referred to as the null value constant. (No 22
instances of the null type can ever be created, and the only way to obtain a null value constant is via this 23
keyword.) 24
The definition of null pointer constant (which Standard C++ requires to be a compile-time expression that 25
evaluates to zero) has been extended to include nullptr. The null value constant can be implicitly 26
converted to any pointer or handle type, in which case it becomes a null pointer value or null value, 27
respectively. This allows nullptr to be used in relational, equality, conditional, and assignment 28
expressions, among others. 29
Object^ obj1 = nullptr; // handle obj1 has the null value 30
String^ str1 ......

阅读全文(3184) | 评论:0

The Common Language Runtime(2005-12-08 11:05:00)

摘要:COM led to a lot of great software and some very useful systems over the years. However, during its lifespan, the problems we just discussed emerged time and again (and we haven’t even mentioned the problems with DCOM). The initial impetus behind COM was the question “How can we compose already-compiled binary software that was developed using different languages and tools?” The answer was “Build reliable, predictable bridges between separate components.” COM concentrated on a well-established boundary—the one between the client and the object. COM makes sure the boundary is well-defined and named so there’s no ambiguity between the client and the object. It eventually became evident that the boundary between the client and the object didn’t necessarily have to exist at all. What if a runtime environment were available that dissolved the boundary between the client and the object? That’s what the common language runtime is all about—erasing the boundaries between components. The commo......

阅读全文(4572) | 评论:0

关于读书(2005-12-08 11:04:00)

摘要:今天突发奇想,其实也算不上什么奇想了,为什么我不把自己每天学习的资料和看过的书籍文章都一起发上来,一方面可以给自己一些充实感;另一方面,也可以在以后适当的时候回过头来查找方便;当然也可以给自己以后留作纪念,或者给其他人留作参考。 呵呵,不错的想法,就从今天开始吧。......

阅读全文(2712) | 评论:0

Pure C++(2005-12-07 10:38:00)

摘要:Visual Studio® 2005 brings the type parameter model of generic programming to the Microsoft® .NET Framework. C++/CLI supports two type parameter mechanisms—common language runtime (CLR) generics and C++ templates. In my last column, I looked at the characteristics that these two mechanisms have in common (see Pure C++: Generic Programming Under .NET). In this column, I'll look at some of the differences—in particular, differences in the parameter list and type constraint model.
Parameter List Redux
The parameter list works like the signature of a function: it identifies the number and kind of each parameter, and associates a unique identifier with each one so that each parameter can be uniquely referred to within the template definition. The parameter serves as a placeholder within the definition of the template or generic type. The user creates object instances of the type by providing actual values to bind to the parameters. The instantiation of a parameterized type ......

阅读全文(3253) | 评论:0

使用 Visual C++ 2005 的现代语言功能编写更快的代码(4)(2005-12-07 10:32:00)

摘要:安全性 在 2002 年,Bill Gates 发出了可信任计算 (Trustworthy Computing) 倡议,这对 Microsoft 开发的所有产品都有着不可小视的冲击力。Windows 操作系统的开发人员在安全性培训和代码评审上花费了几个月的时间,这使得 Windows Server 2003 成为该公司曾经发布过的安全性最高的一个操作系统。Microsoft Office 2003 还包含了许多安全功能,例如 Information Rights Management (IRM)、更好的宏安全性和在 Outlook 中阻止 HTML 下载等等。而编译器小组也在大踏步地使他们开发的编译器及其生成的代码变得更安全。 Visual Studio .NET 2002 引入了缓冲区安全检查 /GS 编译器选项。这一标志将导致编译器在决定为有缓冲区溢出攻击嫌疑的函数返回地址之前就预先在堆栈上分配空间。在函数进入时,一个带有已知计算值的安全 Cookie 会被放在这个缓冲区中,而在函数退出时,编译器会对其进行检查,以确保该 Cookie 没有被破坏。对 Cookie 值的更改意味着有重写返回地址的可能性,而这会产生一个错误并导致应用程序终止。 当然,这并不能防止所有的缓冲区溢出攻击。Visual Studio .NET 2003 还增强了 /GS 功能。它通过对堆栈上的局部变量进行排序来将数组分配在高于其余局部变量的内存地址上,从而防止这些局部变量造成溢出。这样会阻止基于 vtable 入侵的攻击和其他基于指针的攻击。
图 7 原来的 /GS Visual C++ 2005 对这一强大的功能进行了又一次升级。当进行函数调用时,函数的激活记录按照如图 7 所示的方式放置。如果一个局部缓冲区发生了溢出,黑客就有可能重写其堆栈上的所有内容,其中包括异常处理函数记录、安全 cookie、帧指针、返回地址,以及函数的参数。这些值中的大多数都是通过各种机制保护的(例如安全异常处理),然而,在一个以函数指针作为参数的函数中,利用缓冲区溢出仍有可能。如果一个函数将函数指针(或者一个包含函数指针的结构或类)作为参数,黑客就可能会重写这一指针的值,并使代码执行任何他/她想要运行的函数。为了防止这一点,Visual C++ 2005 编译器会分析所有的函数参数......

阅读全文(3496) | 评论:0

使用 Visual C++ 2005 的现代语言功能编写更快的代码(3)(2005-12-07 10:31:00)

摘要:在 Visual Studio .NET 2003 中,C++ Interop 技术被称为 IJW 或“正常运行 (It Just Works)”。在即将推出的版本中,这被改为一个更具描述性的名称“Interop 技术”。那么,它是如何“正常运行”的呢?对于每个由应用程序使用的本机方法而言,编译器同时创建了一个托管的入口点和一个非托管的入口点。它们中的一个是实际的方法实现,而另外一个是转发 thunk,它创建适当的转换并进行任何必要的封送处理。托管入口点几乎总是实际的方法实现,唯一的例外是该方法的代码无法用 MSIL 表示或者开发人员使用“#pragma unmanaged”编译器指令来强制要求将入口点实现为本机代码。 当使用一个 IJW 转发 thunk 时(例如,当本机入口点是转发 thunk 时),编译器提供 thunk 的实现,并通过一个偏移量或导入地址表(Import Address Table,IAT)跳转来调入实际的实现。IJW thunk 的合理时间大约在 50 到 300 个周期之间,不过,精心设计的测试用例可以使这个数字减至 10 那么小。当转发 thunk 是 MSIL 时,托管的 P/Invoke 就会派上用场。P/Invoke 仅包含一个声明而没有实际的方法实现;CLR 提供了对 thunk 的运行时支持的功能。这些转发 thunks 通常都会比同等的本机实现稍微慢一点点。 如上所述,使用 IJW 使每个函数都有两个入口点,一个托管的接口和一个非托管的接口。但某些构造需要这些入口点的调用地点在编译时进行填充(例如函数指针和 vtable)。而如果编译器在编译时无法知道运行时调用地点的托管状态,则它应该选择哪一个入口点呢?在 Visual Studio .NET 2003 中,编译器总是会选择非托管入口点。当然,如果调用方确实是托管的,则上述做法就会造成一些麻烦,这称为 Double P/Invoke 问题,如图 4 所示。在这种情形下,托管调用对非托管 thunk 进行的转换刚好又转换回托管代码,这样的操作会导致几个大的不必要的开销。
图 4 Double P/Invoke 问题 Visual C++ 2005 提出了几个解决方案。第一个方案就是使用 __clrcall 关键字,通过这个关键字,可以指定是否基于每个方......

阅读全文(4180) | 评论:0

使用 Visual C++ 2005 的现代语言功能编写更快的代码(2)(2005-12-07 10:29:00)

摘要:Interop 选择 在 Visual Studio .NET 2003 的所有基于 .NET 框架的语言中,Visual C++ 7.1 提供了最好的 interop 功能。它具有实现实际的 interop 方案所必需的功能,Quake II 到 .NET 框架的移植便是例证,具体细节请访问http://www.vertigosoftware.com/Quake2.htm。Visual C++ 2005 进一步扩展了这一功能。 在托管与本机环境中,使用 .NET Interop 有四种主要途径:COM interop 可以使用 Runtime Callable Wrappers (RCW) 与 COM Callable Wrappers (CCW) 来实现。.通用语言运行库 (CLR) 负责类型封送(除非在极少的情况下使用自定义封送拆收器),并且这些调用的开销很大。您需要非常小心地尽量避免接口往来过于频繁,否则就会出现很严重的性能问题。您还需要保证这些包装一直与其底层的组件保持一致。也就是说,在您因简单的 Interop 场景而试图使用大量的本机 COM 代码时,COM Interop 非常有用。 第二种 Interop 选择是使用 P/Invoke。要达到此目的,可以使用 DLLImport 属性,并且在方法声明中为您想要导入的函数指定属性。封送是按照它在声明中的指定方式来处理的。然而,只有在您有代码需要通过 DLL 导出公开必需的功能时,DLLImport 才是有用的。 当您需要从本机代码调用托管代码时,CLR 宿主也是一种选择。在这种情况下,本机应用程序必须驱动所有的执行:设置主机、绑定到运行库、启动主机、检索适当的 AppDomain、设置调用上下文、查找所需的程序集和类,并调用所需类上的操作。在控制发生什么以及何时发生方面,这无疑是最健壮的解决方案之一,但这也会带来让人难以置信的枯燥,并需要许多自定义代码。 第四种选择,也有可能是最简单并最可行的选择,就是使用 C++ 的 Interop 功能。通过设置 /clr 开关,编译器会生成 MSIL 而不是本机代码。唯一被生成为本机代码的是那些无法被编译成 MSIL 的代码,其中包括带有内联 asm 块的函数,以及使用像 Streaming SIMD Extensions (SSE) 这样一些特定于 ......

阅读全文(3374) | 评论:0