<?xml version="1.0" encoding="GB2312"?> 
<feed version="0.3" xmlns="http://purl.org/atom/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xml:lang="en"> 
<title><![CDATA[yunhai]]></title>
<link rel="alternate" type="text/html" href="http://yunhai.bokee.com/index.html" /> 
<modified>2005-11-29T23:12:12Z</modified> 
<tagline type="text/html" mode="escaped"><![CDATA[<p align="center"> <a href="http://www.yun-hai.net/" target="_blank">www.yun-hai.net</a> 
  主页经常打不开^_^<br/>
  <a href="http://disk.yun-hai.net" target="_blank">disk.yun-hai.net</a> 网络空间可以下到一些您想要的冬冬<br />
  <a href="http://blog.yun-hai.net" target="_blank">blog.yun-hai.net</a> 我的blog就这里了</p>]]></tagline> 
<generator url="http://www.blogdriver.com/" version="2.0">BlogDriver</generator> 
<copyright>Copyright (c) 2004, Yun-Hai</copyright> 

<entry> 
<title><![CDATA[晕,好久不来我blog的域名怎么都变了...]]></title> 
<link rel="alternate" type="text/html" href="http://yunhai.blogchina.com/3699982.html" />  
<issued>2005-11-29T23:12:11Z</issued> 
<created>2005-11-29T23:12:11Z</created> 
<modified>2005-11-29T23:12:11Z</modified>
<id>tag:yunhai.blogchina.com,2005://3699982</id>
<author> 
<name>云海</name> 
<url>http://yunhai.blogchina.com/index.html</url> 
<email>yun_hai@hotmail.com</email> 
</author> 
<dc:subject>我的日志</dc:subject> 
<content type="text/html" mode="escaped" xml:lang="cn" xml:base="http://yunhai.blogchina.com/"> 
<![CDATA[<p>好久没写blog了 呵呵 最近好忙好忙<img src="http://www.blogdriver.com/jsp/face/14.gif" />&amp;nbsp;一年又要过去了</p>]]> 
</content> 
</entry>
 
<entry> 
<title><![CDATA[BCB 编写 DLL 终极手册 ]]></title> 
<link rel="alternate" type="text/html" href="http://yunhai.blogchina.com/1487449.html" />  
<issued>2005-05-11T16:53:37Z</issued> 
<created>2005-05-11T16:53:37Z</created> 
<modified>2005-05-11T16:53:37Z</modified>
<id>tag:yunhai.blogchina.com,2005://1487449</id>
<author> 
<name>云海</name> 
<url>http://yunhai.blogchina.com/index.html</url> 
<email>yun_hai@hotmail.com</email> 
</author> 
<dc:subject>程序设计</dc:subject> 
<content type="text/html" mode="escaped" xml:lang="cn" xml:base="http://yunhai.blogchina.com/"> 
<![CDATA[<p>&amp;nbsp; 由于现在比较多的网友老是在 CSDN 上询问关于 BCB 编写 DLL 的问题，我编写了这篇文章抛砖引玉</p><p>一. 编写 DLL<br />&amp;nbsp; File/New/Dll 生成 Dll 的向导，然后可以添加导出函数和导出类<br />&amp;nbsp; 导出函数：extern &amp;quot;C&amp;quot; __declspec(dllexport) ExportType FunctionName(Parameter)<br />&amp;nbsp; 导出类：class __declspec(dllexport) ExportType ClassName{...}<br />&amp;nbsp; 例子：(说明：只是生成了一个 DLL.dll )</p><p>#include &amp;quot;DllForm.h&amp;quot;&amp;nbsp; // TDllFrm 定义</p><p>USERES(&amp;quot;Dll.res&amp;quot;);<br />USEFORM(&amp;quot;DllForm.cpp&amp;quot;, DllFrm);</p><p>class __declspec(dllexport) __stdcall MyDllClass { //导出类<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; public:<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MyDllClass();<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; void CreateAForm();<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TDllFrm* DllMyForm;<br />};</p><p>TDllFrm* DllMyForm2;<br />extern &amp;quot;C&amp;quot; __declspec(dllexport) __stdcall void CreateFromFunct();//导出函数</p><p>//---------------------------------------------------------------------------<br />int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*)<br />{<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; return 1;<br />}<br />//---------------------------------------------------------------------------</p><p>MyDllClass::MyDllClass()<br />{<br />}</p><p>void MyDllClass::CreateAForm()<br />{<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; DllMyForm = new TDllFrm(Application);<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; DllMyForm-&amp;gt;Show();<br />}<br />//---------------------------------------------------------------------------<br />void __stdcall CreateFromFunct()<br />{<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; DllMyForm2 = new TDllFrm(Application);<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; DllMyForm2-&amp;gt;Show();<br />}</p><p><br />二. 静态调用 DLL<br />使用 $BCB pathBinimplib.exe 生成 Lib 文件，加入到工程文件中<br />将该文件拷贝到当前目录，使用 implib MyDll.lib MyDll.dll 生成<br />// Unit1.h // TForm1 定义<br />#include &amp;quot;DllForm.h&amp;quot; // TDllFrm 定义<br />//---------------------------------------------------------------------------</p><p>__declspec(dllimport) class __stdcall MyDllClass {<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; public:<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MyDllClass();<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; void CreateAForm();<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TDllFrm* DllMyForm;<br />}; <br />extern &amp;quot;C&amp;quot; __declspec(dllimport) __stdcall void CreateFromFunct();</p><p>class TForm1 : public TForm{...}</p><p><br />// Unit1.cpp // TForm1 实现<br />void __fastcall TForm1::Button1Click(TObject *Sender)<br />{ // 导出类实现，导出类只能使用静态方式调用<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; DllClass = new MyDllClass();<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; DllClass-&amp;gt;CreateAForm();&amp;nbsp;&amp;nbsp;&amp;nbsp; <br />}<br />//---------------------------------------------------------------------------<br />void __fastcall TForm1::Button2Click(TObject *Sender)<br />{ // 导出函数实现<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; CreateFromFunct();<br />}<br />//---------------------------------------------------------------------------</p><p>void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &amp;amp;Action)<br />{<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; delete DllClass;<br />}</p><p>三. 动态调用 DLL<br />// Unit1.h <br />class TForm1 : public TForm<br />{<br />&amp;nbsp;...<br />private: // User declarations<br />&amp;nbsp;void (__stdcall *CreateFromFunct)();<br />&amp;nbsp;...<br />}</p><p>// Unit1.cpp // TForm1<br />HINSTANCE DLLInst = NULL;<br />void __fastcall TForm1::Button2Click(TObject *Sender)<br />{<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; if( NULL == DLLInst ) DLLInst = LoadLibrary(&amp;quot;DLL.dll&amp;quot;); //上面的 Dll<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; if (DLLInst) { <br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CreateFromFunct = (void (__stdcall*)()) GetProcAddress(DLLInst,<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;quot;CreateFromFunct&amp;quot;);<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (CreateFromFunct) CreateFromFunct();<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else ShowMessage(&amp;quot;Could not obtain function pointer&amp;quot;);<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; }<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; else ShowMessage(&amp;quot;Could not load DLL.dll&amp;quot;);<br />}</p><p>void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &amp;amp;Action)<br />{<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( DLLInst ) FreeLibrary (DLLInst);<br />}<br />&amp;nbsp; <br />四. DLL 作为 MDIChild (子窗体) 【只编写动态调用的例子】<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; 实际上，调用子窗体的 DLL 时，系统只是检查应用程序的 MainForm 是否为 fsMDIForm 的窗体，这样只</p><p>要把调用程序的 Application 的 Handle 传递给 DLL 的 Application 即可；同时退出 DLL 时也要恢复 </p><p>Application</p><p>// MDIChildPro.cpp // Dll 实现 CPP<br />#include &amp;quot;unit1.h&amp;quot; // TForm1 定义<br />TApplication *SaveApp = NULL;<br />int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*)<br />{<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( (reason==DLL_PROCESS_DETACH) &amp;amp;&amp;amp; SaveApp )<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Application = SaveApp ; // 恢复 Application<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; return 1;<br />}</p><p>extern &amp;quot;C&amp;quot; __declspec(dllexport) __stdcall void TestMDIChild(&amp;nbsp;&amp;nbsp;&amp;nbsp; //1024X768<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; TApplication* mainApp,<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; LPSTR lpCaption)<br />{<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( NULL == SaveApp ) // 保存 Application，传递 Application<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; {<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SaveApp = Application;<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Application = mainApp;<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; }<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; // lpCaption 为子窗体的 Caption<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; TForm1 *Form1 = new TForm1 ( Application, lpCaption ); <br />&amp;nbsp;&amp;nbsp;&amp;nbsp; Form1-&amp;gt;Show();<br />}<br />注：上面的程序使用 BCB 3.0 编译成功</p><p>五. BCB 调用 VC 编写的 DLL<br />&amp;nbsp; 1. 名字分解：<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; 没有名字分解的函数<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TestFunction1 // __cdecl calling convention<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @TestFunction2 // __fastcall calling convention<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TESTFUNCTION3 // __pascal calling convention<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TestFunction4 // __stdcall calling convention<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; 有名字分解的函数<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @TestFunction1$QV // __cdecl calling convention<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @TestFunction2$qv // __fastcall calling convention<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TESTFUNCTION3$qqrv // __apscal calling convention<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @TestFunction4$qqrv // __stdcall calling convention<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; 使用 extern &amp;quot;C&amp;quot; 不会分解函数名</p><p>&amp;nbsp;&amp;nbsp;&amp;nbsp; 使用 Impdef MyLib.def MyLib.DLL 生成 def 文件查看是否使用了名字分解</p><p>&amp;nbsp; 2. 调用约定：<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; __cdecl 缺省<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 是 Borland C++ 的缺省的 C 格式命名约定，它在标识符前加一下划线，以保留<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; 它原来所有的全程标识符。参数按最右边参数优先的原则传递给栈，然后清栈。<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; extaern &amp;quot;C&amp;quot; bool __cdecl TestFunction();<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 在 def 文件中显示为 <br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TestFunction @1<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 注释： @1 表示函数的顺序数，将在“使用别名”时使用。</p><p>&amp;nbsp;&amp;nbsp;&amp;nbsp; __pascal Pascal格式<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 这时函数名全部变成大写，第一个参数先压栈，然后清栈。<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TESTFUNCTION @1 //def file</p><p>&amp;nbsp;&amp;nbsp;&amp;nbsp; __stdcall 标准调用<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 最后一个参数先压栈，然后清栈。<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TestFunction @1 //def file</p><p>&amp;nbsp;&amp;nbsp;&amp;nbsp; __fastcall 把参数传递给寄存器<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 第一个参数先压栈，然后清栈。<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @TestFunction @1 //def file</p><p>&amp;nbsp; 3. 解决调用约定：<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Microsoft 与 Borland 的 __stdcall 之间的区别是命名方式。 Borland 采用<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; __stdcall 的方式去掉了名字起前的下划线。 Microsoft 则是在前加上下划线，在<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; 后加上 @ ，再后跟为栈保留的字节数。字节数取决于参数在栈所占的空间。每一个<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; 参数都舍入为 4 的倍数加起来。这种 Miocrosoft 的 DLL 与系统的 DLL 不一样。</p><p>&amp;nbsp; 4. 使用别名：<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 使用别名的目的是使调用文件 .OBJ 与 DLL 的 .DEF 文件相匹配。如果还没有<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; .DEF 文件，就应该先建一个。然后把 DEF 文件加入 Project。使用别名应不断<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; 修改外部错误，如果没有，还需要将 IMPORTS 部分加入 DEF 文件。<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IMPORTS<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TESTFUNCTIOM4 = DLLprj.TestFunction4<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TESTFUNCTIOM5 = DLLprj.WEP @500<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TESTFUNCTIOM6 = DLLprj.GETHOSTBYADDR @51<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 这里需要说明的是，调用应用程序的 .OBJ 名与 DLL 的 .DEF 文件名是等价的，<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; 而且总是这样。甚至不用考虑调用约定，它会自动匹配。在前面的例子中，函数被<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; 说明为 __pascal，因此产生了大写函数名。这样链接程序不会出错。</p><p>&amp;nbsp; 5. 动态调用例子<br />VC DLL 的代码如下：<br />extern &amp;quot;C&amp;quot; __declspec(dllexport) LPSTR __stdcall BCBLoadVCWin32Stdcall()<br />{<br />&amp;nbsp;static char strRetStdcall[256] = &amp;quot;BCB Load VC_Win32 Dll by __stdcall mode is OK!&amp;quot;;</p><p>&amp;nbsp;return strRetStdcall;<br />} </p><p>extern &amp;quot;C&amp;quot; __declspec(dllexport) LPSTR __cdecl BCBLoadVCWin32Cdecl()<br />{<br />&amp;nbsp;static char strRetCdecl[256] = &amp;quot;BCB Load VC_Win32 Dll by __cdecl mode is OK!&amp;quot;;</p><p>&amp;nbsp;return strRetCdecl;<br />} </p><p>extern &amp;quot;C&amp;quot; __declspec(dllexport) LPSTR __fastcall BCBLoadVCWin32Fastcall()<br />{<br />&amp;nbsp;static char strRetFastcall[256] = &amp;quot;BCB Load VC_Win32 Dll by __fastcall mode is OK!&amp;quot;;</p><p>&amp;nbsp;return strRetFastcall;<br />} </p><p>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 其实动态调用与调用 BCB 编写的 DLL 没有区别，关键是查看 DLL 的导出函数名字<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 可以使用 tdump.exe(BCB工具) 或者 dumpbin.exe(VC工具) 查看<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; tdump -ee MyDll.dll &amp;gt;1.txt (查看 1.txt 文件即可)<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 由于 VC6 不支持 __pascall 方式，下面给出一个三种方式的例子<br />void __fastcall TForm1::btnBLVCWin32DynClick(TObject *Sender)<br />{<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; /*cmd: tdbump VCWin32.dll &amp;gt;1.txt<br />&amp;nbsp;Turbo Dump&amp;nbsp; Version 5.0.16.4 Copyright (c) 1988, 1998 Borland International<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Display of File VCWIN32.DLL</p><p>&amp;nbsp;EXPORT ord:0000='BCBLoadVCWin32Fastcall::'<br />&amp;nbsp;EXPORT ord:0001='BCBLoadVCWin32Cdecl'<br />&amp;nbsp;EXPORT ord:0002='_BCBLoadVCWin32Stdcall@0'<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; */<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( !DllInst )<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DllInst = LoadLibrary ( &amp;quot;VCWin32.dll&amp;quot; );<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( DllInst )<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; {<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; BCBLoadVCWin32Stdcall = (LPSTR (__stdcall *) () )<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GetProcAddress ( DllInst, &amp;quot;<a href="mailto:_BCBLoadVCWin32Stdcall@0">_BCBLoadVCWin32Stdcall@0</a>&amp;quot; ); //VC Dll<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // GetProcAddress ( DllInst, &amp;quot;BCBLoadVCWin32Stdcall&amp;quot; ); //BCB Dll<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( BCBLoadVCWin32Stdcall )<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ShowMessage( BCBLoadVCWin32Stdcall() );<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else ShowMessage ( &amp;quot;Can't find the __stdcall Function!&amp;quot; );</p><p>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; BCBLoadVCWin32Cdecl = (LPSTR (__cdecl *) () )<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GetProcAddress ( DllInst, &amp;quot;BCBLoadVCWin32Cdecl&amp;quot; );<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( BCBLoadVCWin32Cdecl )<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ShowMessage( BCBLoadVCWin32Cdecl() );<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else ShowMessage ( &amp;quot;Can't find the __cdecl Function!&amp;quot; );</p><p>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //Why?不是 'BCBLoadVCWin32Fastcall::',而是 <a href="mailto:'@BCBLoadVCWin32Fastcall@0'">'@BCBLoadVCWin32Fastcall@0'</a>？<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; BCBLoadVCWin32Fastcall = (LPSTR (__fastcall *) () )<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //GetProcAddress ( DllInst, &amp;quot;BCBLoadVCWin32Fastcall::&amp;quot; );<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GetProcAddress ( DllInst, &amp;quot;@BCBLoadVCWin32Fastcall@0&amp;quot; );<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( BCBLoadVCWin32Fastcall )<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ShowMessage( BCBLoadVCWin32Fastcall() );<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else ShowMessage ( &amp;quot;Can't find the __fastcall Function!&amp;quot; );<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; }<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; else ShowMessage ( &amp;quot;Can't find the Dll!&amp;quot; );<br />}</p><p>&amp;nbsp; 6. 静态调用例子<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 静态调用有点麻烦，从动态调用中可以知道导出函数的名字，但是直接时(加入 lib 文件到工程文件) </p><p>Linker 提示不能找到函数的实现<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 从 4 看出，可以加入 def 文件连接<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (可以通过 impdef MyDll.def MyDll.dll 获得导出表)<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 建立与 DLL 文件名一样的 def 文件与 lib 文件一起加入到工程文件<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 上面的 DLL(VCWIN32.dll) 的 def 文件为(VCWIN32.def)：<br />LIBRARY&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; VCWIN32.DLL</p><p>IMPORTS<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; @BCBLoadVCWin32Fastcall&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = <a href="mailto:VCWIN32.@BCBLoadVCWin32Fastcall@0">VCWIN32.@BCBLoadVCWin32Fastcall@0</a><br />&amp;nbsp;&amp;nbsp;&amp;nbsp; _BCBLoadVCWin32Cdecl&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = VCWIN32.BCBLoadVCWin32Cdecl<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; BCBLoadVCWin32Stdcall&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = <a href="mailto:VCWIN32._BCBLoadVCWin32Stdcall@0">VCWIN32._BCBLoadVCWin32Stdcall@0</a></p><p>对应的函数声明和实现如下：<br />extern &amp;quot;C&amp;quot; __declspec(dllimport) LPSTR __fastcall BCBLoadVCWin32Fastcall();<br />extern &amp;quot;C&amp;quot; __declspec(dllimport) LPSTR __cdecl BCBLoadVCWin32Cdecl();<br />extern &amp;quot;C&amp;quot; __declspec(dllimport) LPSTR __stdcall BCBLoadVCWin32Stdcall();</p><p>void __fastcall TfrmStatic::btnLoadDllClick(TObject *Sender)<br />{<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; ShowMessage ( BCBLoadVCWin32Fastcall() );<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; ShowMessage ( BCBLoadVCWin32Cdecl() );<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; ShowMessage ( BCBLoadVCWin32Stdcall() );<br />}<br />注意：在 BCB 5.0 中，可能直接按下 F9 是不能通过 Linker 的，请先 Build 一次<br />注：上面的程序使用 BCB 5.0 与 VC6.0 编译成功</p>]]> 
</content> 
</entry>
 
<entry> 
<title><![CDATA[C++ Builder 5.0编HOOK程序 ]]></title> 
<link rel="alternate" type="text/html" href="http://yunhai.blogchina.com/1487439.html" />  
<issued>2005-05-11T16:52:51Z</issued> 
<created>2005-05-11T16:52:51Z</created> 
<modified>2005-05-11T16:52:51Z</modified>
<id>tag:yunhai.blogchina.com,2005://1487439</id>
<author> 
<name>云海</name> 
<url>http://yunhai.blogchina.com/index.html</url> 
<email>yun_hai@hotmail.com</email> 
</author> 
<dc:subject>程序设计</dc:subject> 
<content type="text/html" mode="escaped" xml:lang="cn" xml:base="http://yunhai.blogchina.com/"> 
<![CDATA[<p>一,</p><p>HINSTANCE g_hinstDll = NULL;<br />HHOOK g_hhook&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = NULL;<br />HWND&amp;nbsp; g_hwndPost&amp;nbsp; = NULL;<br />UINT&amp;nbsp; g_uMsgNotify = WM_USER;</p><p><br />HOOKPROC KeyboardHook_HookProc ( int nCode, WPARAM wParam, LPARAM lParam)<br />{<br />&amp;nbsp; LRESULT lResult = CallNextHookEx(g_hhook, nCode, wParam, lParam);<br />&amp;nbsp; if (nCode == HC_ACTION)<br />&amp;nbsp; {<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PostMessage(g_hwndPost, g_uMsgNotify, wParam, lParam);<br />&amp;nbsp; }<br />&amp;nbsp; return((HOOKPROC)lResult);<br />}<br />///////////<br />BOOL WINAPI SetKeyboardHook (HWND hWndPost, UINT Msg)<br />{<br />&amp;nbsp; HHOOK hhook;<br />&amp;nbsp; if (g_hhook != NULL) return(FALSE);<br />&amp;nbsp; g_hwndPost&amp;nbsp; = hWndPost;<br />&amp;nbsp; g_uMsgNotify = Msg;<br />&amp;nbsp; Sleep(0);<br />&amp;nbsp; if&amp;nbsp; (g_hLogHook==NULL)<br />&amp;nbsp; hhook = SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyboardHook_HookProc,g_hinstDll, 0);<br />&amp;nbsp; InterlockedExchange((PLONG) &amp;amp;g_hhook, (LONG) hhook);<br />&amp;nbsp; return(g_hhook != NULL);<br />}<br />///<br />BOOL WINAPI ReleaseKeyboardHook()<br />{<br />&amp;nbsp; BOOL fOK = TRUE;</p><p>&amp;nbsp; if (g_hhook != NULL)<br />&amp;nbsp; {<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fOK = UnhookWindowsHookEx(g_hhook);<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; g_hhook = NULL;<br />&amp;nbsp; }<br />&amp;nbsp; return(fOK);<br />}</p><p>BOOL WINAPI DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved)<br />{<br />&amp;nbsp; switch (fdwReason)<br />&amp;nbsp; {<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; case DLL_PROCESS_ATTACH:<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; g_hinstDll = hinstDll;<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;<br />&amp;nbsp; }<br />&amp;nbsp; return(TRUE);<br />}</p><p /><p>二,</p><p>在Borland的Community上找到了这篇文章，可以解决这个问题了。如下：<br /><a href="http://community.borland.com/article/0,1410,20008,00.html">http://community.borland.com/article/0,1410,20008,00.html</a><br />///<br />C++Builder 4.0 is the first C++Builder compiler that supports shared memory segments. This document explains how to use this feature in windows DLL. </p><p>To change the data segment and the class name, you need to add #pragma option -zR[SEGMENT NAME] and #pragma option -zT[CLASS NAME] to the file you want the data shared from. Below is the source file I am going to export the integer named 'data': </p><p>File: SharedData.cpp <br />//---------------------------------------------------------------------------<br />// Borland C++Builder<br />// Copyright (c) 1987, 1999 Inprise Corporation. All Rights Reserved.<br />//---------------------------------------------------------------------------</p><p>#pragma option -zRSHSEG&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // change default data segment name<br />#pragma option -zTSHCLASS&amp;nbsp;&amp;nbsp;&amp;nbsp; // change default data class name</p><p>// Here is the initialized data that will be shared.<br />int data = 0;</p><p>Notice that the segment name for this file is: SHSEGSHCLASS. A .def file is required for the linker to create the shared segement. Below is what the .def file looks like: </p><p>File: Shared.def <br />LIBRARY SHAREDDLL</p><p>SEGMENTS<br />&amp;nbsp; SHSEG CLASS 'SHCLASS' SHARED</p><p /><p><br />三</p><p>当你的DLL程序被其它各个程序调用时，每调用一次，将产生一个<br />DLL的实例，其实代码在内存中仅有一套，但DLL中的变量即数据段将<br />产生多个，这若干个数据段是互不干扰、是不能共享的，但在一些特<br />殊情况下，就不能满足我们的要求了，比如，用户的全局钩子程序就<br />是一个.DLL,这个.DLL会被内存所有的进程调用， 如果它的数据段不<br />能共享，就变成了多个局部钩子了，好在API已替你想好了一个间接<br />办法，你可用一个“共享名”申请一块共享内存块，进行读写：</p><p>HANDLE&amp;nbsp; GetShare(char * &amp;amp;ShareP,int size,char *ShareName)<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp; ShareP申请的内存块地址，size字节数，ShareName共享名<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; HANDLE fh=CreateFileMapping((HANDLE)-1,0,<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PAGE_READWRITE,0,<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Size,<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ShareName);<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ShareP=(char *)MapViewOfFile(fh,<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FILE_MAP_ALL_ACCESS,<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0,0,0);<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (GetLastError()!=ERROR_ALREADY_EXISTS)<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ZeroMemory(ShareP,size);&amp;nbsp; // 共享区初始化<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return(fh);<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }</p><p>char * ShareP=NULL;<br />void&amp;nbsp; test()&amp;nbsp; // 申请一块128个字节的字符数组<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; HANDLE fh=GetShare(ShareP,128,&amp;quot;ShareForMyProg&amp;quot;);<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int i=0;i&amp;lt;128;i++)<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ShareP[i]=i;<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CloseHandle(fh);<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }</p><p>&amp;nbsp;&amp;nbsp;&amp;nbsp; 如果你的多个程序之间或同一个程序多次同时运行，也可借助这个办法进<br />变量通讯;<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; 在VC++中，若要为DLL定义一个共享内存段更简单，这是一种直接定义的<br />办法:<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #pragma&amp;nbsp;&amp;nbsp;&amp;nbsp; data_seg(&amp;quot;Shared&amp;quot;)<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int x,y;<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; char s[128];<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #pragma&amp;nbsp;&amp;nbsp;&amp;nbsp; data_seg<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #pragma&amp;nbsp;&amp;nbsp;&amp;nbsp; comment(linker,&amp;quot;/section:Shared,rws&amp;quot;)</p><p>真简单，可惜在C++BUILDER5.0中经试验好象不能接受这种方法;<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; 对于BCB，能不能实现DLL中直接定义共享内存块内，请看下列一段文字：</p><p><br /><a href="http://community.borland.com/article/0,1410,20008,00.html">http://community.borland.com/article/0,1410,20008,00.html</a><br />///<br />C++Builder 4.0 is the first C++Builder compiler that supports shared memory segments.</p><p>This document explains how to use this feature in windows DLL. </p><p>To change the data segment and the class name, you need to add <br />#pragma option -zR[SEGMENT NAME] and <br />#pragma option -zT[CLASS NAME] to the file you want the data shared from. <br />Below is the source file I am going to export the integer named 'data': </p><p>File: SharedData.cpp <br />//---------------------------------------------------------------------------<br />// Borland C++Builder<br />// Copyright (c) 1987, 1999 Inprise Corporation. All Rights Reserved.<br />//---------------------------------------------------------------------------</p><p>#pragma option -zRSHSEG&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // change default data segment name<br />#pragma option -zTSHCLASS&amp;nbsp;&amp;nbsp;&amp;nbsp; // change default data class name</p><p>// Here is the initialized data that will be shared.<br />int data = 0;</p><p>Notice that the segment name for this file is: SHSEGSHCLASS. A .def file <br />is required for the linker to create the shared segement. Below is what the <br />.def file looks like: </p><p>File: Shared.def <br />LIBRARY SHAREDDLL</p><p>SEGMENTS<br />&amp;nbsp; SHSEG CLASS 'SHCLASS' SHARED&amp;nbsp; </p><p>可见C++BUILDER4.0与DELPHI已能提供直接实现DLL内存段共享问题，请高手邦忙一起<br />试一试：在BCB或DELPHI具体应怎样做?</p><p /><p /><p>四</p><p>// 下面的程序将产生有三个导出函数的MouseHook.DLL<br />#include <windows.h /><br />#pragma argsused<br />typedef&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 为共享区定义结构<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; struct<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; POINT&amp;nbsp; MouseLoc;&amp;nbsp; // 存放鼠标位置<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; HHOOK&amp;nbsp; NewHook;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 存放新钩子句柄<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int&amp;nbsp;&amp;nbsp;&amp;nbsp; LoadCount;&amp;nbsp; // DLL装入次数计数<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp; TShareMem;<br />TShareMem&amp;nbsp; *ShareMem=NULL;</p><p>HINSTANCE&amp;nbsp; DllHinst;<br />int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)<br />{<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; DllHinst=hinst;<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; static HANDLE&amp;nbsp; fh;&amp;nbsp; // DLL共享区句柄<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; if (reason==DLL_PROCESS_ATTACH)&amp;nbsp;&amp;nbsp;&amp;nbsp; // DLL入口<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 为共享区申请共享单元<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fh=CreateFileMapping((HANDLE)-1,0,<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PAGE_READWRITE,0,<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sizeof(TShareMem),<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;quot;ShareForMouseHook&amp;quot;);<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ShareMem=(TShareMem *)MapViewOfFile(fh,<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FILE_MAP_ALL_ACCESS,<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0,0,0);<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (GetLastError()!=ERROR_ALREADY_EXISTS)<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ZeroMemory(ShareMem,sizeof(TShareMem));<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 共享区初始化<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ShareMem-&amp;gt;LoadCount+=1;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 装入计数<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; if (reason==DLL_PROCESS_DETACH)&amp;nbsp; // DLL出口处理<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ShareMem-&amp;gt;LoadCount-=1;<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CloseHandle(fh);<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; return 1;<br />}<br />extern &amp;quot;C&amp;quot; __declspec(dllexport)<br />void GetMouse(int &amp;amp;mx,int &amp;amp;my,int &amp;amp;loadcount)&amp;nbsp; // DLL导出函数GetMouse()<br />{<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; if (ShareMem!=NULL)<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mx=ShareMem-&amp;gt;MouseLoc.x;<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; my=ShareMem-&amp;gt;MouseLoc.y;<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; loadcount=ShareMem-&amp;gt;LoadCount;<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }<br />}<br />LRESULT CALLBACK MouseHook(int nCode,<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; WPARAM wParam,LPARAM lParam)<br />{<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; if (nCode==HC_ACTION)<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MOUSEHOOKSTRUCT *l=(MOUSEHOOKSTRUCT *)lParam;<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ShareMem-&amp;gt;MouseLoc=l-&amp;gt;pt;&amp;nbsp; //送鼠标位置<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; return(CallNextHookEx(ShareMem-&amp;gt;NewHook,nCode,wParam,lParam));<br />}<br />extern &amp;quot;C&amp;quot; __declspec(dllexport)<br />void EnableHook()&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 导出函数EnableHook()<br />{<br />&amp;nbsp; if (ShareMem!=NULL)<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (ShareMem-&amp;gt;NewHook==NULL)&amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp; 安装新钩子<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ShareMem-&amp;gt;NewHook=SetWindowsHookEx(WH_MOUSE,<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (HOOKPROC)MouseHook,<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DllHinst,0);<br />}<br />extern &amp;quot;C&amp;quot; __declspec(dllexport)<br />void DisableHook()&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 导出函数DisableHook()<br />{<br />&amp;nbsp; if (ShareMem!=NULL)<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; if (ShareMem-&amp;gt;NewHook!=NULL)<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UnhookWindowsHookEx(ShareMem-&amp;gt;NewHook);<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ShareMem-&amp;gt;NewHook=NULL; // 卸掉新钩子<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }<br />}</p><p>//=======================================================================</p><p>#include <vcl.h /><br />#pragma hdrstop<br />#include &amp;quot;CallUnit1.h&amp;quot;<br />#pragma package(smart_init)<br />#pragma resource &amp;quot;*.dfm&amp;quot;<br />TForm1 *Form1;<br />//---------------------------------------------------------------------------<br />__fastcall TForm1::TForm1(TComponent* Owner)<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : TForm(Owner)<br />{<br />}<br />//---------------------------------------------------------------------------</p><p>extern &amp;quot;C&amp;quot; __declspec(dllimport)<br />void&amp;nbsp; EnableHook();&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // DLL导入函数1<br />extern &amp;quot;C&amp;quot; __declspec(dllimport)<br />void&amp;nbsp; DisableHook();&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // DLL导入函数2<br />extern &amp;quot;C&amp;quot; __declspec(dllimport)<br />void&amp;nbsp; GetMouse(int &amp;amp;mx,int &amp;amp;my,int &amp;amp;loadcount); // DLL导入函数3</p><p>void __fastcall TForm1::Button1Click(TObject *Sender)<br />{<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; EnableHook();<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; int x,y,loadcount;<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; while (!Application-&amp;gt;Terminated)<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp; // 不停在从DLL中取回鼠标位置<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GetMouse(x,y,loadcount);<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Edit1-&amp;gt;Text=String(x)+&amp;quot;,&amp;quot;+String(y)+&amp;quot;:&amp;quot;+String(loadcount);<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Application-&amp;gt;ProcessMessages();<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }<br />}<br />void __fastcall TForm1::Button2Click(TObject *Sender)<br />{<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; DisableHook();<br />}<br />void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &amp;amp;Action)<br />{<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; DisableHook();<br />}<br />//---------------------------------------------------------------------------</p><p /><p><br />五<br />步骤如下：<br />&amp;nbsp; 在DLL中的工程中，假设为MouseHook.bpr(产生MouseHook.DLL)<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1.在Unit1.cpp的最前面（#include <windows.h />之前)加上<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #pragma option -zRSHSEG&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 改变缺省数据段名<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #pragma option -zTSHCLASS&amp;nbsp;&amp;nbsp;&amp;nbsp; // 改变缺省数据类名<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2.新建一工程同名的纯文本文件MouseHook.def,其内容只要<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 一行：<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SEGMENTS&amp;nbsp;&amp;nbsp;&amp;nbsp; SHSEG&amp;nbsp;&amp;nbsp;&amp;nbsp; CLASS&amp;nbsp;&amp;nbsp;&amp;nbsp; 'SHCLASS'&amp;nbsp; SHARED<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 并将此文件用Project-&amp;gt;Add Project增加到工程中；<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3.在你的程序代码的前面定义的全局变量都将是DLL共享的，<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 在Unit1.cpp中，例如：<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; <br />// 下面的程序将产生有三个导出函数的MouseHook.DLL<br />// 纯文本文件&amp;nbsp; MouseHook.def的内容如下:<br />// SEGMENTS&amp;nbsp;&amp;nbsp;&amp;nbsp; SHSEG&amp;nbsp;&amp;nbsp;&amp;nbsp; CLASS&amp;nbsp;&amp;nbsp;&amp;nbsp; 'SHCLASS'&amp;nbsp; SHARED</p><p>#pragma option -zRSHSEG&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 改变缺省数据段名<br />#pragma option -zTSHCLASS&amp;nbsp;&amp;nbsp;&amp;nbsp; // 改变缺省数据类名</p><p>#include <windows.h /><br />#pragma argsused<br />// 以下都将是共享区内存变量<br />POINT&amp;nbsp; MouseLoc={0,0};&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 存放鼠标位置<br />HHOOK&amp;nbsp; NewHook=NULL;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 存放新钩子句柄<br />int&amp;nbsp;&amp;nbsp;&amp;nbsp; LoadCount=0;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // DLL装入次数计数</p><p>HINSTANCE&amp;nbsp; DllHinst;<br />int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)<br />{<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; DllHinst=hinst;<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; if (reason==DLL_PROCESS_ATTACH)&amp;nbsp;&amp;nbsp;&amp;nbsp; // DLL入口<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LoadCount+=1;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 装入计数<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; else<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (reason==DLL_PROCESS_DETACH) // DLL出口处理<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LoadCount-=1;<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; return 1;<br />}<br />extern &amp;quot;C&amp;quot; __declspec(dllexport)<br />void GetMouse(int &amp;amp;mx,int &amp;amp;my,int &amp;amp;js)&amp;nbsp; // DLL导出函数GetMouse()<br />{<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; mx=MouseLoc.x;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 送出鼠标位置<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; my=MouseLoc.y;<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; js=LoadCount;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 送出DLL装入次数<br />}<br />LRESULT CALLBACK MouseHook(int nCode,<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; WPARAM wParam,LPARAM lParam)<br />{<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; if (nCode==HC_ACTION)<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MOUSEHOOKSTRUCT *l=(MOUSEHOOKSTRUCT *)lParam;<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MouseLoc=l-&amp;gt;pt;&amp;nbsp; //送鼠标位置<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; return(CallNextHookEx(NewHook,nCode,wParam,lParam));<br />}<br />extern &amp;quot;C&amp;quot; __declspec(dllexport)<br />void EnableHook()&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 导出函数EnableHook()<br />{<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (NewHook==NULL)&amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp; 安装新钩子<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; NewHook=SetWindowsHookEx(WH_MOUSE,<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (HOOKPROC)MouseHook,<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DllHinst,0);<br />}<br />extern &amp;quot;C&amp;quot; __declspec(dllexport)<br />void DisableHook()&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 导出函数DisableHook()<br />{<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; if (NewHook!=NULL)<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UnhookWindowsHookEx(NewHook);<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; NewHook=NULL; // 卸掉新钩子<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }<br />}<br />//==========================================================<br />// CallHook.EXE,将调用全局鼠标全局钩子MouseHook.DLL<br />// 静态装入MouseHook.DLL,工程中须用 MouseGook.Lib<br />#include <vcl.h /><br />#pragma hdrstop<br />#include &amp;quot;CallUnit1.h&amp;quot;<br />#pragma package(smart_init)<br />#pragma resource &amp;quot;*.dfm&amp;quot;<br />TForm1 *Form1;<br />//---------------------------------------------------------------------------<br />__fastcall TForm1::TForm1(TComponent* Owner)<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : TForm(Owner)<br />{<br />}<br />//---------------------------------------------------------------------------</p><p>extern &amp;quot;C&amp;quot; __declspec(dllimport)<br />void&amp;nbsp; EnableHook();&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // DLL导入函数1<br />extern &amp;quot;C&amp;quot; __declspec(dllimport)<br />void&amp;nbsp; DisableHook();&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // DLL导入函数2<br />extern &amp;quot;C&amp;quot; __declspec(dllimport)<br />void&amp;nbsp; GetMouse(int &amp;amp;mx,int &amp;amp;my,int &amp;amp;loadcount); // DLL导入函数3</p><p>void __fastcall TForm1::Button1Click(TObject *Sender)<br />{<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; EnableHook();<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; int x,y,loadcount;<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; while (!Application-&amp;gt;Terminated)<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp; // 不停在从DLL中取回鼠标位置<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GetMouse(x,y,loadcount);<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Edit1-&amp;gt;Text=String(x)+&amp;quot;,&amp;quot;+String(y);<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Edit2-&amp;gt;Text=loadcount;&amp;nbsp; // 显示DLL装入次数<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Application-&amp;gt;ProcessMessages();<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }<br />}<br />void __fastcall TForm1::Button2Click(TObject *Sender)<br />{<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; DisableHook();<br />}<br />void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &amp;amp;Action)<br />{<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; DisableHook();<br />}<br />// ok,已经深夜1点了，别忘了给俺加点分!!!!!!!!!!!!!!!!</p><p /><p><br />六</p><p /><p>VC的程序</p><p><br />#include <windows.h /><br />#include <windowsx.h /><br />#include <tchar.h /></p><p>HINSTANCE g_hinstDll = NULL;</p><p>#pragma data_seg(&amp;quot;.drectve&amp;quot;)<br />&amp;nbsp;&amp;nbsp;&amp;nbsp; static char szLinkDirectiveShared[] = &amp;quot;-section:Shared,rws&amp;quot;;<br />#pragma data_seg()<br />#pragma data_seg(&amp;quot;Shared&amp;quot;)</p><p>HHOOK g_hhook&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = NULL;<br />HWND&amp;nbsp; g_hwndPost&amp;nbsp; = NULL;<br />UINT&amp;nbsp; g_uMsgNotify = WM_USER;</p><p>#pragma data_seg()</p><p>static LRESULT WINAPI KeyboardHook_HookProc (<br />&amp;nbsp; int nCode,<br />&amp;nbsp; WPARAM wParam, <br />&amp;nbsp; LPARAM lParam) <br />{</p><p>&amp;nbsp; LRESULT lResult = CallNextHookEx(g_hhook, nCode, wParam, lParam);</p><p>&amp;nbsp; if (nCode == HC_ACTION) <br />&amp;nbsp; {<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PostMessage(g_hwndPost, g_uMsgNotify, wParam, lParam);<br />&amp;nbsp; }<br />&amp;nbsp; return(lResult);<br />}</p><p>BOOL WINAPI SetKeyboardHook (HWND hWndPost, UINT Msg) <br />{<br />&amp;nbsp; HHOOK hhook;</p><p>&amp;nbsp; if (g_hhook != NULL) return(FALSE);</p><p>&amp;nbsp; g_hwndPost&amp;nbsp; = hWndPost;<br />&amp;nbsp; g_uMsgNotify = Msg;<br />&amp;nbsp; Sleep(0);</p><p>&amp;nbsp; hhook = SetWindowsHookEx(WH_KEYBOARD, KeyboardHook_HookProc, g_hinstDll, 0);<br />&amp;nbsp; InterlockedExchange((PLONG) &amp;amp;g_hhook, (LONG) hhook);<br />&amp;nbsp; return(g_hhook != NULL);<br />}</p><p>BOOL WINAPI ReleaseKeyboardHook() <br />{<br />&amp;nbsp; BOOL fOK = TRUE;</p><p>&amp;nbsp; if (g_hhook != NULL) <br />&amp;nbsp; {<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fOK = UnhookWindowsHookEx(g_hhook);<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; g_hhook = NULL;<br />&amp;nbsp; }<br />&amp;nbsp; return(fOK);<br />}</p><p>BOOL WINAPI DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved) <br />{<br />&amp;nbsp; switch (fdwReason) <br />&amp;nbsp; {<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; case DLL_PROCESS_ATTACH:<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; g_hinstDll = hinstDll;<br />&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;<br />&amp;nbsp; }<br />&amp;nbsp; return(TRUE);<br />} </p>]]> 
</content> 
</entry>
 
<entry> 
<title><![CDATA[整理了一下blog]]></title> 
<link rel="alternate" type="text/html" href="http://yunhai.blogchina.com/1487425.html" />  
<issued>2005-05-11T16:51:05Z</issued> 
<created>2005-05-11T16:51:05Z</created> 
<modified>2005-05-11T16:51:05Z</modified>
<id>tag:yunhai.blogchina.com,2005://1487425</id>
<author> 
<name>云海</name> 
<url>http://yunhai.blogchina.com/index.html</url> 
<email>yun_hai@hotmail.com</email> 
</author> 
<dc:subject>我的日志</dc:subject> 
<content type="text/html" mode="escaped" xml:lang="cn" xml:base="http://yunhai.blogchina.com/"> 
<![CDATA[<p>&amp;nbsp; 前段时间blogchina系统更新搞的我n久都不能正常使用了，今天上来看看速度还可以所以更新了一下blog，把下沉的文章都处理了。最近工作和生活都好忙郁闷。。。</p>]]> 
</content> 
</entry>
 
<entry> 
<title><![CDATA[心目中的编程高手]]></title> 
<link rel="alternate" type="text/html" href="http://yunhai.blogchina.com/1171654.html" />  
<issued>2005-04-11T20:59:12Z</issued> 
<created>2005-04-11T20:59:12Z</created> 
<modified>2005-04-11T20:59:12Z</modified>
<id>tag:yunhai.blogchina.com,2005://1171654</id>
<author> 
<name>Yun-Hai</name> 
<url>http://yunhai.blogchina.com/index.html</url> 
<email>yun_hai@hotmail.com</email> 
</author> 
<dc:subject>其它文章</dc:subject> 
<content type="text/html" mode="escaped" xml:lang="cn" xml:base="http://yunhai.blogchina.com/"> 
<![CDATA[MIT BBS上说微软电话面试的一道题就是&amp;quot;Who do you think is the best coder, and why?&amp;quot;。我觉得挺有意思的，也来凑个热闹。排名不分先后。 <br /><br /><p>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; </p><p>&amp;nbsp;</p><div>MIT BBS上说微软电话面试的一道题就是&amp;quot;Who do you think is the best coder, and why?&amp;quot;。我觉得挺有意思的，也来凑个热闹。排名不分先后。 <br /><br />Bill Joy, 前任Sun的首席科学家，当年在Berkeley时主持开发了最早版本的BSD。他还是vi和csh的作者。当然，Csh Programming Considered Harmful 是另一个话题乐。据说他想看看自己能不能写个操作系统，就在三天里写了个自己的Unix, 也就是BSD的前身。当然是传说了，但足见他的功力。另一个传说是，1980年初的时候，DARPA让BBN在Berkley Unix里加上BBN开发的TCP/IP代码。但当时还是研究生的B伯伯怒了，拒绝把BBN TCP/IP加入BSD，因为他觉得BBN的TCP/IP写得不好。于是B伯伯出手了，端的是一箭封喉，很快就写出了高性能的伯克利版TCP/IP。当时BBN和DARPA签了巨额合同开发TCP/IP Stack，谁知他们的代码还不如一个研究生的好。于是他们开会。只见当时B伯伯穿个T-shirt出现在会议室(当时穿T-shirt不象现在，还是相当散漫的哈)。只见BBN问：你怎么写出来的？而B伯伯答：简单，你读协议，然后编程就行了。最令偶晕倒的是，B伯伯硕士毕业 后决定到工业界发展，于是就到了当时只有一间办公室的Sun, 然后他就把Sparc设计出 来乐。。。象这种软硬通吃的牛人，想不佩服都不行的说。据Bill Joy的同事说，一般开会的时候B伯伯总是拿一堆杂志漫不经心地读。但往往在关键之处，B伯伯发言，直切要害，提出 漂亮的构想，让同事们彻底崩溃。对了，他还是Java Spec和JINI的主要作者之一。 <br /><br /><br />John Carmack，ID Software的founder和Lead Programmer。上个月和一个搞图形的师兄聊天，他竟然不知道John Carmack, 也让偶大大地晕了一把。不过也许搞研究的和搞实战的多少有些隔吧。想必喜欢第一人称射击游戏的都知道J哥哥。90年代初只要能在PC上搞个小动画都能让人惊叹一番的时候，J哥哥就推出了石破天惊的Castle Wolfstein, 然后再接再励，doom, doomII, Quake...每次都把3-D技术推到极 <br />限。J哥哥的简历上说自己的专长是&amp;quot;Exhaust 3-D technology&amp;quot;，真是牛人之言不我欺的说。做J哥哥这样的人是很幸福的，因为各大图形卡厂家一有了新产品就要向他&amp;quot;进贡&amp;quot; ，不然如果他的游戏不支持哪种卡，哪种卡基本就会夭折乐。当初MS的Direct3D也得听取 他的意见，修改了不少API。当然，J哥哥在结婚前十数年如一日地每天编程14小时以上， 也是偶们凡人望尘莫及的。对了，J哥哥高中肆业(？)，可以说是自学成才。不过呢，谁要用这个例子来为自己学习不好辩护，就大错特错了。那Leonardo Da Vinci还是自学成才呢(人是私生子，不能上学)。普通人和天才还是有区别的。对了，其实偶们叫&amp;quot;达分奇&amp;quot;是相当不对的，因为Vinci是地名，而Da Vinci就是从Vinci来的人的意思。换句话说，Leonardo Da Vinci就是&amp;quot;从Vinci来的Leonardo&amp;quot;的意思。叫别人&amp;quot;Da Vinci&amp;quot;就不知所谓乐。嗯，扯远了，打住。 <br /><br />David Cutler，VMS和Windows NT的首席设计师，去微软前号称硅谷最牛的kernel开发员。当初他和他的手下在微软一周内把一个具备基本功能的bootable kernel写出来，然后说：&amp;quot;who can't write an OS in a week?&amp;quot;，也是牛气冲天的说。顺便说一句，D爷爷到NT3.5时，管理1500名开发员，自己还兼做设计和编程，不改coder本色啊。 <br /><br />D爷爷天生脾气火爆，和人争论时喜欢双手猛击桌子以壮声势。<img style="WIDTH: 65px; HEIGHT: 74px" alt="Smile" src="http://forum.blogchina.com/images/smiles/icon_smile.gif" border="0" /> 日常交谈F-word不离口。他面试秘书时必问：&amp;quot;what do you think of the word 'fuck'?&amp;quot; ，让无数美女刹羽而归。终于有一天，一个同样火爆的女面对这个问题脱口而出：&amp;quot;That's my favorite word&amp;quot;。于是她被录取乐，为D爷爷工作到NT3.5发布。 <br /><br />Don Knuth。高爷爷其实用不着偶多说。学编程的不知道他就好像学物理的不知道牛顿，学数学的不知道欧拉，学音乐的不知道莫扎特，学Delphi的不知到Anders Hejlsberg，或者学Linux不知道Linus Torvalds一样，不可原谅啊。<img style="WIDTH: 65px; HEIGHT: 74px" alt="Smile" src="http://forum.blogchina.com/images/smiles/icon_smile.gif" border="0" />为了让文章完整，就再罗唆几句吧。高爷爷本科时就开始给行行色色的公司写各种稀奇古怪的编译器挣外快了。他卖给别人时收一两千美元，那些公司拿了code，加工一下卖出去就是上万上十万。不过也没见高爷爷不爽过，学者本色的说。想想那可是60年代初啊，高爷爷写编译器写多了，顺带就搞出了个Attribute Grammar和LR(k)，大大地造福后人啊。至于高爷爷在CalTech的编程比赛(有Alan Kay得众多高高手参加)总是第一，写的Tex到86年就code freeze，还附带2^n美分奖励等等都是耳熟能详的，偶就不饶舌乐。 <br /><br />顺便说一下，高老大爷是无可争议的写作高手。他给Concrete Mathematics 写的前言可谓字字铿锵，堪为前言的典范。他的技术文章也是一绝，文风细致，解释精当，而且没有学究气，不失轻快跳脱。记得几年前读Concrete Mathemathics，时不时开怀大笑，让老妈极其郁闷，觉得我nerdy到家，不可救药。其实呢，子非鱼，安知鱼之乐，更不知那完全是高爷爷的功劳。说到写作高手，不能不提Stephen A. Cook。他的文章当年就被我们的写作老师极力推荐，号称典雅文风的样本。库爷爷一头银发，身材颀长，总是面带谦和的微笑，颇有仙风道骨，正好和他的仙文相配的说。 <br /><br />高爷爷其实还是开源运动的先驱。虽然他没有象Richard Stallman那样八方奔走，但他捐献了好多作品，都可以在网上看到，比如著名的Mathematical Writing，MMIXWare，The Tex Book等，更不用说足以让他流芳百世的Tex乐。 <br /><br />Ken Thompson，C语言前身B语言的作者，Unix的发明人之一(另一个是Dennis M. Riche老大，被尊为DMR)，Belle(一个厉害的国际象棋程序)的作者之一, 操作系统Plan 9的主要作者(另一个是大牛人Rob Pike, 前不久被google挖走了)。Ken爷爷也算是计算机历史上开天辟地的人物了。1969年还是计算机史前时代，普通人都认为只有大型机才能运行通用的操作系统，小型机只有高山仰止的份儿。至于用高级语言来写操作系统，更是笑谈。Ken爷爷自然不是池中物，于是他和DMR怒了，在1969年到1970间用汇编在PDP-7上写出了UNIX的第一个版本。他们并不知道，一场轰轰烈烈的UNIX传奇由此拉开了序幕。Ken爷爷在1971年又把Unix用C重写，于是C在随后20年成就了不知多少豪杰的梦想和光荣。 <br /><br />Ken爷爷还有段佳话： 装了UNIX的PDP-11最早被安装在Bell Lab里供大家日常使用。很快大家就发现Ken爷爷总能进入他们的帐户，获得最高权限。Bell Lab里的科学家都心比天高，当然被搞得郁闷无比。于是有高手怒了，跳出来分析了UNIX代码，找到后门，修改代码，然后重新编译了整个UNIX。就在大家都以为&amp;quot;这个世界清净了&amp;quot;的时候，他们发现Ken爷爷还是轻而易举地拿到他们的帐户权限，百思不解后，只好继续郁闷。谁知道这一郁闷，就郁闷了14年，直到Ken爷爷道出个中缘由。原来，代码里的确有后门，但后门不在Unix代码里，而在编译Unix代码的C编译器里。每次C编译器编译UNIX的代码，就自动生成后门代码。而整个Bell Lab的人，都是用Ken爷爷的C编译器。<img style="WIDTH: 95px; HEIGHT: 109px" alt="Very Happy" src="http://forum.blogchina.com/images/smiles/icon_biggrin.gif" border="0" /></div><div>(6)Rob Pike, AT&amp;amp;T Bell Lab前Member of Technical Staff ，现在google研究操作系统 <br />。罗伯伯是Unix的先驱，是贝尔实验室最早和Ken Thompson以及Dennis M. Ritche开发 <br />Unix的猛人，UTF-8的设计人。他还在美国名嘴David Letterman的晚间节目上露了一小脸 <br />，一脸憨厚地帮一胖子吹牛搞怪。让偶佩服不已的是，罗伯伯还是1980年奥运会射箭的银 <br />牌得主。他还是个颇为厉害的业余天文学家，设计的珈玛射线望远镜差点被NASA用在航天 <br />飞机上。他还是两本经典，The Unix Programming Environment 和 The Practice of <br />Programming 的作者之一。如果初学者想在编程方面精益求精，实在该好好读读这两本书 <br />。它们都有中文版的说。罗伯伯还写出了Unix下第一个基于位图的窗口系统，并且是著名 <br />的blit 终端的作者。当然了，罗伯伯还是号称锐意革新的操作系统，Plan9，的主要作者 <br />。可惜的是，Plan9并没有引起多少人的注意。罗伯伯一怒之下，写出了振聋发聩的雄文 <br />Systems Software Research is Irrelevant，痛斥当下系统开发的不思进取，固步自封 <br />的弊病。虽然这篇文章是罗伯伯含忿出手，颇有偏激之词，但确实道出了系统开发的无奈 <br />：开发周期越来越长，代价越来越大，用户被统一到少数几个系统上，结果越来越多的活 <br />动是测量和修补，而真正的革新越来越少。 <br /><br />就在罗伯伯郁闷之极的时候，google登门求贤来乐。如果说现在还有一家大众公司在不遗 <br />余力地把系统开发推向极致的话，也就是google乐。随便看看google的成果就知道了。具 <br />有超强容错和负载平衡能力的分布式文件系统GFS (现在能够用100,000台廉价PC搭起一个 <br />巨型分布系统，并且高效便宜地进行管理的系统也不多哈)，大规模机器学习系统(拼写检 <br />查，广告匹配，拼音搜寻。。。哪个都很牛的说)，更不用说处理海量并行计算的各式 <br />google服务了。Rob在System Software Research is Irrelevant里萧瑟地说现在没有人 <br />再关心系统研究的前沿成果了。想不到他错了，应为google关心。google网络了大批功成 <br />总是试图吸取系统研究的最新成果。想必Rob Pike在google很幸福。愿他做出更棒的系统 <br /></div>]]> 
</content> 
</entry>
 
<entry> 
<title><![CDATA[网络游戏：律师与外挂的对话之五（关于虚拟财产）]]></title> 
<link rel="alternate" type="text/html" href="http://yunhai.blogchina.com/996121.html" />  
<issued>2005-03-22T22:41:55Z</issued> 
<created>2005-03-22T22:41:55Z</created> 
<modified>2005-03-22T22:41:55Z</modified>
<id>tag:yunhai.blogchina.com,2005://996121</id>
<author> 
<name>Yun-Hai</name> 
<url>http://yunhai.blogchina.com/index.html</url> 
<email>yun_hai@hotmail.com</email> 
</author> 
<dc:subject>其它文章</dc:subject> 
<content type="text/html" mode="escaped" xml:lang="cn" xml:base="http://yunhai.blogchina.com/"> 
<![CDATA[<p>注：作为关于网络游戏发展的律师，我很想有机会能够一些外挂的制造者或者精通外挂技术的专业人士一起，探讨关于外挂的相关法律问题。本文就是我和一位精通外挂的技术高手的对话整理摘录，希望对你我正确认识外挂，正确区分&amp;quot;外挂&amp;quot;和&amp;quot;私服&amp;quot;提供一些有益的帮助。</p><p>原文链接:http://www.donews.com/donews/article/5/56865.html</p><br /><strong>网络游戏：律师与外挂的对话之五（关于虚拟财产）</strong><br /><span style="FONT-SIZE: 9pt">(这条文章已经被阅读了<font color="#023996"> 696</font>次) 时间：2003年12月26日 22:43　来源：商建刚 网络游戏</span><br /><br /><table align="right" border="0"><tbody><tr><td></td></tr></tbody></table><p>注：作为关于网络游戏发展的律师，我很想有机会能够一些外挂的制造者或者精通外挂技术的专业人士一起，探讨关于外挂的相关法律问题。本文就是我和一位精通外挂的技术高手的对话整理摘录，希望对你我正确认识外挂，正确区分&amp;quot;外挂&amp;quot;和&amp;quot;私服&amp;quot;提供一些有益的帮助。</p><p><strong>第五部分：关于虚拟财产</strong></p><p>2003-12-26 21:31:58 网络游戏外挂的制造者<br />关于保护虚拟财产你有什么想法么？ </p><p>2003-12-26 21:31:06 网络游戏专业委员会律师商建刚<br />我写了一篇文章。你可以看看。 </p><p>2003-12-26 21:32:17 网络游戏外挂的制造者<br />哪里？ </p><p>2003-12-26 21:32:46 网络游戏外挂的制造者<br />我觉得这个虚拟财产的保护绝对要谨慎， </p><p>2003-12-26 21:33:06 网络游戏外挂的制造者<br />否则会扰乱社会秩序 </p><p>2003-12-26 21:32:09 网络游戏专业委员会律师商建刚<br /><a href="http://www.lawfan.com/asp/readNews.asp?flag=1&amp;id=5789&amp;cname">http://www.lawfan.com/asp/readNews.asp?flag=1&amp;amp;id=5789&amp;amp;cname</a>= </p><p>2003-12-26 21:37:46 网络游戏外挂的制造者<br />熟悉网络游戏技术的人应该知道，网络游戏中的每一个ID、装备都是唯一的，即便是看是完全相同的&amp;quot;宝物&amp;quot;，其源代码是不同的。 </p><p>2003-12-26 21:37:56 网络游戏外挂的制造者<br />这个论点有问题 </p><p>2003-12-26 21:37:02 网络游戏专业委员会律师商建刚<br />怎么说。 </p><p>2003-12-26 21:38:17 网络游戏外挂的制造者<br />并不一定 </p><p>2003-12-26 21:39:00 网络游戏外挂的制造者<br />这是要看游戏开发者的设定的 </p><p>2003-12-26 21:37:55 网络游戏专业委员会律师商建刚<br />你有办法创造源代码相同的宝物？ </p><p>2003-12-26 21:39:33 网络游戏外挂的制造者<br />宝物是没有源代码的 </p><p>2003-12-26 21:39:51 网络游戏外挂的制造者<br />宝物是一个数据包 </p><p>2003-12-26 21:38:48 网络游戏专业委员会律师商建刚<br />有一个代码。 </p><p><br />2003-12-26 21:40:13 网络游戏外挂的制造者<br />可以是所有一样的宝物共享一个数据包 </p><p>2003-12-26 21:39:06 网络游戏专业委员会律师商建刚<br />对，是数据。这个数据是确定的。 </p><p>2003-12-26 21:40:19 网络游戏外挂的制造者<br />也可以是每个宝物有自己的数据包 </p><p>2003-12-26 21:42:11 网络游戏外挂的制造者<br />比如说A刀，在游戏中所有的A刀属性都是一样的，就是说有一样的攻击力，那么游戏开发者完全可以赋予这个A刀一个代码，比如1000，如果玩</p><p>家ID的物品拦中有1000这个代码就表示他拥用A刀 </p><p>2003-12-26 21:42:28 网络游戏外挂的制造者<br />能理解么 </p><p>2003-12-26 21:42:41 网络游戏外挂的制造者<br />当然也有如你所说的那样的 </p><p>2003-12-26 21:41:36 网络游戏专业委员会律师商建刚<br />这个能理解。 </p><p>2003-12-26 21:42:15 网络游戏专业委员会律师商建刚<br />但是，这个A是什么时间创造出来，服务器上是唯一的，不同的时间，地点，是从哪个怪物身长出来，这是唯一的呀。 </p><p><br />2003-12-26 21:43:40 网络游戏外挂的制造者<br />但是服务器可以不纪录这些信息 </p><p>2003-12-26 21:42:54 网络游戏专业委员会律师商建刚<br />这就是服务器本身的技术等级不够。 </p><p>2003-12-26 21:44:04 网络游戏外挂的制造者<br />因为这些信息对于有的游戏设定来说是没有用的 </p><p>2003-12-26 21:44:44 网络游戏外挂的制造者<br />不能这么说啊，人家不需要这些信息为什么一定要报存这些信息浪费储存空间呢？ </p><p>2003-12-26 21:44:16 网络游戏专业委员会律师商建刚<br />这是游戏安全的需要，也是防止作弊的需要。 </p><p>2003-12-26 21:46:01 网络游戏外挂的制造者<br />这个不能这样说的，除非区分高级和低级物品 </p><p>2003-12-26 21:46:16 网络游戏外挂的制造者<br />否则低级物品会占用大量资源 </p><p>2003-12-26 21:45:23 网络游戏专业委员会律师商建刚<br />我明白了。好了，今天就讨论到这里，我需要消化消化。 </p><p>2003-12-26 21:46:37 网络游戏外挂的制造者<br />呵呵 </p><p>2003-12-26 21:45:48 网络游戏专业委员会律师商建刚<br />的确如此，也让更多的人知道事实的真相。 </p><p>2003-12-26 21:46:05 网络游戏专业委员会律师商建刚<br />我要整理我们的谈话了，下次再聊。 </p><p><br />2003-12-26 21:47:17 网络游戏外挂的制造者<br />我的想法是虚拟的东西是掌握在游戏商手里的，游戏商可以任意制作 </p><p>2003-12-26 21:46:25 网络游戏专业委员会律师商建刚<br />这个我赞同。 <br /></p>]]> 
</content> 
</entry>
 
<entry> 
<title><![CDATA[网络游戏：律师与外挂的对话之四（外挂犯罪？！）]]></title> 
<link rel="alternate" type="text/html" href="http://yunhai.blogchina.com/996059.html" />  
<issued>2005-03-22T22:35:48Z</issued> 
<created>2005-03-22T22:35:48Z</created> 
<modified>2005-03-22T22:35:48Z</modified>
<id>tag:yunhai.blogchina.com,2005://996059</id>
<author> 
<name>Yun-Hai</name> 
<url>http://yunhai.blogchina.com/index.html</url> 
<email>yun_hai@hotmail.com</email> 
</author> 
<dc:subject>其它文章</dc:subject> 
<content type="text/html" mode="escaped" xml:lang="cn" xml:base="http://yunhai.blogchina.com/"> 
<![CDATA[<p>注：作为关于网络游戏发展的律师，我很想有机会能够一些外挂的制造者或者精通外挂技术的专业人士一起，探讨关于外挂的相关法律问题。本文就是我和一位精通外挂的技术高手的对话整理摘录，希望对你我正确认识外挂，正确区分&amp;quot;外挂&amp;quot;和&amp;quot;私服&amp;quot;提供一些有益的帮助。</p><p>原文链接:http://www.donews.com/donews/article/5/56864.html</p><br /><strong>网络游戏：律师与外挂的对话之四（外挂犯罪？！）</strong><br /><span style="FONT-SIZE: 9pt">(这条文章已经被阅读了<font color="#023996"> 877</font>次) 时间：2003年12月26日 22:41　来源：商建刚 网络游戏</span><br /><br /><table align="right" border="0"><tbody><tr><td></td></tr></tbody></table><strong><p>注：作为关于网络游戏发展的律师，我很想有机会能够一些外挂的制造者或者精通外挂技术的专业人士一起，探讨关于外挂的相关法律问题。本文就是我和一位精通外挂的技术高手的对话整理摘录，希望对你我正确认识外挂，正确区分&amp;quot;外挂&amp;quot;和&amp;quot;私服&amp;quot;提供一些有益的帮助。</p></strong><p><strong>第四部分：关于犯罪</strong></p><p>2003-12-26 20:46:33 网络游戏专业委员会律师商建刚<br />我知道公安部认为是无罪的。现在处理的是扫黄打非办负责。这主要原因是，现在关于外挂是侵犯了著作权的观点，呼声较高，且比较有市场。</p><p>2003-12-26 20:48:20 网络游戏外挂的制造者<br />扫黄打非不是也是要公安局的人去的么 </p><p>2003-12-26 20:47:55 网络游戏专业委员会律师商建刚<br />公安不是扫黄打非办。 </p><p>2003-12-26 20:57:53 网络游戏专业委员会律师商建刚<br />第二百一十七条 以营利为目的，有下列侵犯著作权情形之一，违法所得数额较大或者有其他严重情节的，处三年以下有期徒刑或者拘役，并处或者单处罚金；违法所得数额巨大或者有其他特别严重情节的，处三年以上七年以下有期徒刑，并处罚金：<br />（一）未经著作权人许可，复制发行其文字作品、音乐、电影、电视、录像作品、计算机软件及其他作品的；<br />（二）出版他人享有专有出版权的图书的；<br />（三）未经录音录像制作者许可，复制发行其制作的录音录像的；<br />（四）制作、出售假冒他人署名的美术作品的。<br /></p><p>2003-12-26 20:58:22 网络游戏专业委员会律师商建刚<br />这侵犯著作权罪，你认为构成么？ </p><p>2003-12-26 20:59:22 网络游戏外挂的制造者<br />未经著作权人许可，复制发行其文字作品、音乐、电影、电视、录像作品、计算机软件及其他作品的；不构成。因为即使在外挂中直接将计算机软件的小段程序加入，并不意味着复制发行该计算机软件。因为这段小程序既不是软件主要部分，也不是软件的大部分。就好比写书引用了别人的书上的一段话 。此外，其他没有复制程序一部分的外挂，更提不上是侵犯著作权了。 <br />&amp;nbsp; </p><p>2003-12-26 20:59:20 网络游戏专业委员会律师商建刚<br />第二百二十五条违反国家规定，有下列非法经营行为之一，扰乱市场秩序，情节严重的，处五年以下有期徒刑或者拘役，并处或者单处违法所得一倍以上五倍以下罚金；情节特别严重的，处五年以上有期徒刑，并处违法所得一倍以上五倍以下罚金或者没收财产：</p><p>　　（一）未经许可经营法律、行政法规规定的专营、专卖物品或者其他限制买卖的物品的；</p><p>　　（二）买卖进出口许可证、进出口原产地证明以及其他法律、行政法规规定的经营许可证或者批准文件的；</p><p>　　（三）其他严重扰乱市场秩序的非法经营行为。<br />&amp;nbsp;</p><p>2003-12-26 21:03:29 网络游戏外挂的制造者<br />嗯，我也想知道有关非法经营的问题。未经许可经营法律、行政法规规定的专营、专卖物品或者其他限制买卖的物品的；这条能算得上。那么就要证明如何扰乱市场秩序了。 首先，外挂是否扰乱了针对该游戏的市场呢？</p><p>2003-12-26 21:03:29 网络游戏专业委员会律师商建刚<br />这个应该不算。国家并没有现在买卖外挂。法律没有明确。 </p><p>2003-12-26 21:05:03 网络游戏外挂的制造者<br />可是现在五部委的文件有没有法律效力呢 </p><p>2003-12-26 21:09:27 网络游戏专业委员会律师商建刚<br />主要从著作权的角度来写文件的。看来是被误导了。</p><p>2003-12-26 21:05:53 网络游戏专业委员会律师商建刚<br />第二百一十九条 有下列侵犯商业秘密行为之一，给商业秘密的权利人造成重大损失的，处三年以下有期徒刑或者拘役，并处或者单处罚金；造成特别严重后果的，处三年以上七年以下有期徒刑，并处罚金：<br />（一）以盗窃、利诱、胁迫或者其他不正当手段获取权利人的商业秘密的；<br />（二）披露、使用或者允许他人使用以前项手段获取的权利人的商业秘密的；<br />（三）违反约定或者违反权利人有关保守商业秘密的要求，披露、使用或者允许他人使用其所掌握的商业秘密的。<br />明知或者应知前款所列行为，获取、使用或者披露他人的商业秘密的，以侵犯商业秘密论。<br />本条所称商业秘密，是指不为公众所知悉，能为权利人带来经济利益，具有实用性并经权利人采取保密措施的技术信息和经营信息。<br />本条所称权利人，是指商业秘密的所有人和经商业秘密所有人许可的商业秘密使用人。<br />&amp;nbsp;</p><p>2003-12-26 21:08:42 网络游戏外挂的制造者<br />比如说,由广告说某一个润滑油,减少了汽油耗量,增加了汽车寿命,应该说这也是影响了汽油/汽车商的销量,算不算扰乱市场次序呢? 何况,外挂是不是影响了游戏上的收入还两说。 </p><p>2003-12-26 21:10:04 网络游戏外挂的制造者<br />私服肯定是侵犯著作权了 </p><p>&amp;nbsp;2003-12-26 21:13:17 网络游戏外挂的制造者<br />真的可以这么说,那些当官的连什么是外挂都不知道 </p><p>2003-12-26 21:13:27 网络游戏专业委员会律师商建刚<br />　[&amp;quot;私服&amp;quot;、&amp;quot;外挂&amp;quot;违法行为是指未经许可或授权，破坏合法出版、他人享有著作权的互联网游戏作品的技术保护措施、修改作品数据、私自架设服务器、制作游戏充值卡(点卡)，运营或挂接运营合法出版、他人享有著作权的互联网游戏作品，从而谋取利益、侵害他人利益。]&amp;quot;私服&amp;quot;、&amp;quot;外挂&amp;quot;违法行为属于非法互联网出版活动，应依法予以严厉打击。<br />&amp;nbsp;<br />2003-12-26 21:13:52 网络游戏专业委员会律师商建刚<br />你看看，是否是这样的。我出去一下。听听你的辩解意见。 </p><p>2003-12-26 21:15:14 网络游戏外挂的制造者<br />私自架设服务器、制作游戏充值卡,这个当然是违法的。制作游戏充值卡,嗬嗬那帮当官的真是饭桶,有这种事情么?如果有这不是诈骗么。破坏合法出版、他人享有著作权的互联网游戏作品的技术保护措施、修改作品数据 。这一点,首先著作权法中有类似的规定么? 破坏合法出版、他人享有著作权的互联网游戏作品的技术保护措施, 就这一条, 有2种不同的含义1比如,有一个软件,发布时加了反拷贝功能,破解该功能是破坏技术保护措施。2 有的软件 。不想让其他人作出和其兼容的产品或附加产品，对其数据储存或数据通讯做了加密处理或者使用自己定义的格式，那么其他人为了制作与其兼容的产品，或附加产品，对其算法进行分析，最后制作除兼容产品或附加产品，这个也可以是说破坏技术保护措施。这两种情况，我想完全应该区别对待，而且前一种情况，只要不复制再发行而牟利，也不能算是违法。修改作品数据？ </p><p>2003-12-26 21:25:09 网络游戏专业委员会律师商建刚<br />著作权人有&amp;quot;保护作品完整权&amp;quot; </p><p>2003-12-26 21:27:57 网络游戏外挂的制造者<br />2001年的软件保护条例里有，软件使用者可以根据自己的需要修改或改进软件的功能，但是不能将修改后的软件提供给别人。对于制作外挂的人，并没有将修改后的软件提供给别人。而是提供自己单独开发的软件。</p><p>2003-12-26 21:30:11 网络游戏外挂的制造者<br />我觉得既然是法律就要有的逻辑性和严密性，不能因为某些人不满就曲解法律，滥用法律 </p><p>2003-12-26 21:30:22 网络游戏专业委员会律师商建刚<br />我们的对话可以整理一下，然后发出来么。当然会省略你的名字。 </p><p>2003-12-26 21:31:33 网络游戏外挂的制造者<br />可以 </p>]]> 
</content> 
</entry>
 
<entry> 
<title><![CDATA[网络游戏：律师与外挂的对话之三（外挂的技术机理）]]></title> 
<link rel="alternate" type="text/html" href="http://yunhai.blogchina.com/995955.html" />  
<issued>2005-03-22T22:22:33Z</issued> 
<created>2005-03-22T22:22:33Z</created> 
<modified>2005-03-22T22:22:33Z</modified>
<id>tag:yunhai.blogchina.com,2005://995955</id>
<author> 
<name>Yun-Hai</name> 
<url>http://yunhai.blogchina.com/index.html</url> 
<email>yun_hai@hotmail.com</email> 
</author> 
<dc:subject>其它文章</dc:subject> 
<content type="text/html" mode="escaped" xml:lang="cn" xml:base="http://yunhai.blogchina.com/"> 
<![CDATA[<p>注：作为关于网络游戏发展的律师，我很想有机会能够一些外挂的制造者或者精通外挂技术的专业人士一起，探讨关于外挂的相关法律问题。本文就是我和一位精通外挂的技术高手的对话整理摘录，希望对你我正确认识外挂，正确区分&amp;quot;外挂&amp;quot;和&amp;quot;私服&amp;quot;提供一些有益的帮助。</p><p>原文链接:http://www.donews.com/donews/article/5/56863.html</p><br /><strong>网络游戏：律师与外挂的对话之三（外挂的技术机理）</strong><br /><span style="FONT-SIZE: 9pt">(这条文章已经被阅读了<font color="#023996"> </font>次) 时间：2003年12月26日 22:38　来源：商建刚 网络游戏</span><br /><br /><table align="right" border="0"><tbody><tr><td></td></tr></tbody></table><p>注：作为关于网络游戏发展的律师，我很想有机会能够一些外挂的制造者或者精通外挂技术的专业人士一起，探讨关于外挂的相关法律问题。本文就是我和一位精通外挂的技术高手的对话整理摘录，希望对你我正确认识外挂，正确区分&amp;quot;外挂&amp;quot;和&amp;quot;私服&amp;quot;提供一些有益的帮助。</p><p><strong>第三部分：关于外挂的技术机理</strong></p><p>2003-12-26 20:18:36 网络游戏专业委员会律师商建刚<br />外挂的技术机理是什么呢？简单的说。</p><p>2003-12-26 20:19:54 网络游戏外挂的制造者<br />一般我认为有2种外挂。1是挂机类外挂。2是作弊类外挂。 2种外挂都可以是模拟通讯，也可是模拟鼠标或者分析修改游戏内。挂机类外挂就是将一系列的动作智能化的组合在一起，让玩家可以不用动手，计算机自动打怪升级。a,如果是模拟通讯的程序：当服务器发来有怪的信息，外挂根据玩家事先的设定，将模拟打怪的数据报发送给服务器。如果服务器传来的信息是血不够了法不够了，外挂就根据用户实现的设定发送吃药的数据包给服务器 。b.如果是模拟鼠标，外挂就按照一定的规律给游戏客户端发送模拟的鼠标点击移动消息，让客户端以为是用户在操作。作弊类外挂，就是利用服务器判别数据的缺陷，自行或者让游戏客户端发送不正常的数据包给服务器。这种不正常的数据报经过服务器解释后可能使用户的状态发生未由游戏开发商定义的变化。 </p><p>2003-12-26 20:27:14 网络游戏专业委员会律师商建刚<br />作弊类外挂是否是这样的。玩家只进行了一项操作，比如说只砍了一刀，外挂向服务器发送了5个数据包，服务器认为玩家砍了五刀。 </p><p>2003-12-26 20:28:36 网络游戏外挂的制造者<br />这个有点特殊，等会再说。先说顺移。比如玩家坐标在100，100，那么这时候玩家任何移动的数据包正常都是应该是这样的：从100，100向100，105移动。但是，作弊数据包可能是直接说从500，500到500，505移动，如果服务器没有判别起始坐标的合法性，那么用户就实现了顺移 。又如复制，刷钱，那就更简单了，如果发送的数据包是给某甲-1w块钱，服务器如果不判别负数那就耍钱了</p><p>2003-12-26 20:31:03 网络游戏专业委员会律师商建刚<br />这是怎么做到的呢？说技术机理。 </p><p><br />2003-12-26 20:33:16 网络游戏外挂的制造者<br />实现方式有2种，如果是模拟通讯的外挂，因为其本生有发送服务器可以识别的数据的能力，所以只要在接受到玩家指令的时候发送这样一个数据包就可以。如果是分析修改内存的外挂，那么只要在客户端在数据打包发向服务器之前将内存中的数据包内容修改掉，也就可以实现了 </p><p>2003-12-26 20:34:32 网络游戏专业委员会律师商建刚<br />如果是模拟通讯的外挂，因为其本生有发送服务器可以识别的数据的能力，所以只要在接受到玩家指令的时候发送这样一个数据包就可以了。达到了替换的目的？</p><p><br />2003-12-26 20:36:17 网络游戏外挂的制造者<br />不一定是替换啊，客户端不发包，外挂也可以自己发包的 </p><p>2003-12-26 20:38:03 网络游戏专业委员会律师商建刚<br />看来这里面还是有区别的。设想你想要写一个Windows的程序，但是你需要使用一个未公开的API。Microsoft 不会提供给你信息的，因此你不得不自己寻找。美国法律通常允许你反汇编Windows的一部份和调用秘密函数，即使Microsoft说你不能。类似的，Microsoft 不能阻止 Samba小组对Windows的文件共享作逆向工程。 </p><p>2003-12-26 20:39:31 网络游戏外挂的制造者<br />是啊，是有不少区别的，但是要构成计算机犯罪应该是肯定不会了</p>]]> 
</content> 
</entry>
 
<entry> 
<title><![CDATA[网络游戏：律师与外挂的对话之二（外挂侵犯著作权？！）]]></title> 
<link rel="alternate" type="text/html" href="http://yunhai.blogchina.com/995933.html" />  
<issued>2005-03-22T22:19:46Z</issued> 
<created>2005-03-22T22:19:46Z</created> 
<modified>2005-03-22T22:19:46Z</modified>
<id>tag:yunhai.blogchina.com,2005://995933</id>
<author> 
<name>Yun-Hai</name> 
<url>http://yunhai.blogchina.com/index.html</url> 
<email>yun_hai@hotmail.com</email> 
</author> 
<dc:subject>其它文章</dc:subject> 
<content type="text/html" mode="escaped" xml:lang="cn" xml:base="http://yunhai.blogchina.com/"> 
<![CDATA[<p>注：作为关于网络游戏发展的律师，我很想有机会能够一些外挂的制造者或者精通外挂技术的专业人士一起，探讨关于外挂的相关法律问题。本文就是我和一位精通外挂的技术高手的对话整理摘录，希望对你我正确认识外挂，正确区分&amp;quot;外挂&amp;quot;和&amp;quot;私服&amp;quot;提供一些有益的帮助。</p><p>原文链接:http://www.donews.com/donews/article/5/56862.html</p><br /><strong>网络游戏：律师与外挂的对话之二（外挂侵犯著作权？！）</strong><br /><span style="FONT-SIZE: 9pt">(这条文章已经被阅读了<font color="#023996"> </font>次) 时间：2003年12月26日 22:34　来源：商建刚 网络游戏</span><br /><br /><table align="right" border="0"><tbody><tr><td></td></tr></tbody></table><p>注：作为关于网络游戏发展的律师，我很想有机会能够一些外挂的制造者或者精通外挂技术的专业人士一起，探讨关于外挂的相关法律问题。本文就是我和一位精通外挂的技术高手的对话整理摘录，希望对你我正确认识外挂，正确区分&amp;quot;外挂&amp;quot;和&amp;quot;私服&amp;quot;提供一些有益的帮助。</p><p><strong>第二部分：关于著作权</strong><br />2003-12-26 20:13:22 网络游戏专业委员会律师商建刚<br />人家的外形，怪物，等等，你有没有复制？ </p><p>2003-12-26 20:14:17 网络游戏外挂的制造者<br />没有。没有人傻倒去做这个 </p><p>2003-12-26 20:14:20 网络游戏专业委员会律师商建刚<br />没有复制？怎么会没有复制人家的图片，文字？ </p><p>2003-12-26 20:15:22 网络游戏外挂的制造者<br />当然没有啊。外挂里一般都不要图像的。怪物的图片、文字，本来就在服务器上。在游戏客户端里也有。外挂的目的是帮助用户实现游戏实现不了的功能，而图片形象文字本来游戏里都有，外挂没有必要去复制 </p><p>2003-12-26 20:16:48 网络游戏专业委员会律师商建刚<br />在游戏客户端里也有？外挂也是客户端呀。外挂有两种，一种是能够独立使用的外挂，一种是必须和客户端一起使用的外挂。</p><p>2003-12-26 20:18:15 网络游戏外挂的制造者<br />对，独立使用的外挂为什么还需要图片呢？ </p><p>2003-12-26 20:17:46 网络游戏专业委员会律师商建刚<br />我知道了问题的关键。 </p><p>2003-12-26 20:18:36 网络游戏外挂的制造者<br />你见过作的和游戏一样有图形可看的外挂么？ </p><p>2003-12-26 20:18:08 网络游戏专业委员会律师商建刚<br />这个问题过。下一个问题：<br /></p>]]> 
</content> 
</entry>
 
<entry> 
<title><![CDATA[网络游戏：律师与外挂的对话之一（外挂侵犯商业秘密？！）]]></title> 
<link rel="alternate" type="text/html" href="http://yunhai.blogchina.com/995838.html" />  
<issued>2005-03-22T22:09:19Z</issued> 
<created>2005-03-22T22:09:19Z</created> 
<modified>2005-03-22T22:09:19Z</modified>
<id>tag:yunhai.blogchina.com,2005://995838</id>
<author> 
<name>Yun-Hai</name> 
<url>http://yunhai.blogchina.com/index.html</url> 
<email>yun_hai@hotmail.com</email> 
</author> 
<dc:subject>其它文章</dc:subject> 
<content type="text/html" mode="escaped" xml:lang="cn" xml:base="http://yunhai.blogchina.com/"> 
<![CDATA[<p>注：作为关于网络游戏发展的律师，我很想有机会能够一些外挂的制造者或者精通外挂技术的专业人士一起，探讨关于外挂的相关法律问题。本文就是我和一位精通外挂的技术高手的对话整理摘录，希望对你我正确认识外挂，正确区分&amp;quot;外挂&amp;quot;和&amp;quot;私服&amp;quot;提供一些有益的帮助。</p><p>原文链接:http://www.donews.com/donews/article/5/56861.html</p><br /><strong>网络游戏：律师与外挂的对话之一（外挂侵犯商业秘密？！）</strong><br /><span style="FONT-SIZE: 9pt">(这条文章已经被阅读了<font color="#023996"> 962</font>次) 时间：2003年12月26日 22:31　来源：商建刚 网络游戏</span><br /><br /><table align="right" border="0"><tbody><tr><td></td></tr></tbody></table><p>注：作为关于网络游戏发展的律师，我很想有机会能够一些外挂的制造者或者精通外挂技术的专业人士一起，探讨关于外挂的相关法律问题。本文就是我和一位精通外挂的技术高手的对话整理摘录，希望对你我正确认识外挂，正确区分&amp;quot;外挂&amp;quot;和&amp;quot;私服&amp;quot;提供一些有益的帮助。</p><p><strong>第一部分：关于商业秘密</strong></p><p>2003-12-26 19:21:57 网络游戏外挂的制造者<br />有关游戏外挂的法律问题，据说做奇迹外挂的被抓了？ </p><p>2003-12-26 19:22:12 网络游戏专业委员会律师商建刚<br />是吧。应该没有事情的，我知道公安部的态度，一般不构成犯罪。现在还没有办法定罪。侵犯著作权罪。我认为，这是目前为止唯一的可能。</p><p>2003-12-26 19:24:11 网络游戏外挂的制造者<br />什么情况下构成犯罪呢？如果卖钱是不是不能个人卖否则就是非法经营？嗬嗬，不过我觉得制作有的外挂是不违反法律的。不过中国的法律没有规定反编译程序是违法的啊 </p><p><br />2003-12-26 19:43:35 网络游戏专业委员会律师商建刚<br />你的外挂是怎么制作的。你有没有通过黑客的方式到运营商的服务器上复制程序？<br />&amp;nbsp;<br />2003-12-26 19:44:24 网络游戏外挂的制造者<br />当然没有。我早就不做这种勾当了。实际操作是，我反编译游戏的客户端，自己写程序模拟客户端发送合法游戏数据 </p><p>2003-12-26 19:46:26 网络游戏专业委员会律师商建刚<br />我知道了，现在很多的外挂都是这样的吧。是很多，还是全部？你是分析游戏的客户端和服务器之间的收据交换流，然后自行写的程序，达到模拟客户端发送的合法游戏收据的效果？</p><p><br />2003-12-26 19:47:21 网络游戏外挂的制造者<br />基本上都是这样的，因为作外挂并不需要服务器端得程序。这在技术上叫做逆向工程。还有不少外挂直接模拟鼠标操作，分析客户端程序内存状态的。都差不多 。</p><p>2003-12-26 19:49:52 网络游戏专业委员会律师商建刚<br />好的。我可以认定，外挂的制作者一定不构成涉及计算机犯罪的三个罪。现在讨论侵犯著作权的事情。你有没有复制人家的程序？复制人家的客户端程序？ </p><p>2003-12-26 19:52:48 网络游戏外挂的制造者<br />外挂中，可能会包括客户端程序的代码的一小段。当然也可能不包括。比如客户端和服务器端的数据通讯是加密的，而且不是使用国际标准的加密算法，那么为了发出的数据服务器能够识别，所以需要将该加密算法提取出来在外挂中使用，可以是直接拿客户端中的这段代码，也可以是自己分析理解后重新写。</p><p>2003-12-26 19:54:32 网络游戏专业委员会律师商建刚<br />为什么要包括，这一小段主要是派什么用场？这里面是否涉及到侵犯人家的商业秘密？将该加密算法提取出来在外挂中使用，这是一种情况。第二种情况，直接拿客户端中的这段代码抄袭，达到混淆的目的。 <br />&amp;nbsp;<br />2003-12-26 19:59:18 网络游戏外挂的制造者<br />那就要看什么叫商业秘密了。如果概算法是该公司申请专利，并且是该公司的利润来源，那我想可以算商业秘密。其实，就是说，数据加密算法本身也没有创新性。其实，就是说，数据加密算法本身也没有创新性。其唯一目的就是让游戏通讯数据不被窃听。当然，另外也增加了制作外挂的难度。&amp;nbsp; </p><p>2003-12-26 20:00:04 网络游戏专业委员会律师商建刚<br />算法，肯定不能申请专利。算法应该可以算是加密的东西，你有没有破译人家的密码？ </p><p>2003-12-26 20:03:18 网络游戏外挂的制造者<br />你所谓的密码是什么密码。比如说，密码是1 可以把abcd加密成bcde </p><p>2003-12-26 20:03:06 网络游戏专业委员会律师商建刚<br />&amp;quot;数据加密算法&amp;quot;就是我说的密码 </p><p>2003-12-26 20:04:47 网络游戏外挂的制造者<br />只能叫做破解了加密算法。破解=逆向工程 </p><p>2003-12-26 20:04:29 网络游戏专业委员会律师商建刚<br />你知道人家的算法么？ </p><p>2003-12-26 20:05:33 网络游戏外挂的制造者<br />可以通过逆向工程知道。在这里逆向工程就是把一段二进制代码的程序复原成一般人比较容易读懂的程序代码 </p><p>2003-12-26 20:07:30 网络游戏专业委员会律师商建刚<br />我的问题是：外挂的制造者是否必须知道，肯定知道客户端和服务器端之间数据交换的数据加密算法？ </p><p>2003-12-26 20:08:37 网络游戏外挂的制造者<br />有的知道，有的不知道 </p><p>2003-12-26 20:08:26 网络游戏专业委员会律师商建刚<br />不知道的人，就是复制这个小程序就行了。对吧？</p><p>2003-12-26 20:09:24 网络游戏外挂的制造者<br />知道的就可以制作功能比较强的外挂，模拟客户端发送数据，甚至制作不需要客户端的程序。不知道的，只能通过模拟鼠标操作或其他上层的手段来制作外挂 </p><p>2003-12-26 20:09:30 网络游戏专业委员会律师商建刚<br />不知道的，就是必须要附加在客户端使用，对吧。 </p><p>2003-12-26 20:10:51 网络游戏外挂的制造者<br />知道算法的分2种，一种是直接复制这段小程序，一种是自己重写一边这个小程序。基本上大部分外挂都要附加在客户端使用的，这是外挂名称的由来 。极少数才能做出不需要客户端的程序 </p><p>2003-12-26 20:12:43 网络游戏专业委员会律师商建刚<br />这个问题先放一放。我撂下一个问题。 <br /></p>]]> 
</content> 
</entry>
 

</feed>