??xml version="1.0" encoding="utf-8" standalone="yes"?>污污的视频在线观看,久久99国产精品久久99,国产精品久久久久三级http://www.aygfsteel.com/chalmers/category/48192.htmlzh-cnThu, 31 Mar 2011 04:05:38 GMTThu, 31 Mar 2011 04:05:38 GMT60Win32环境下动态链接库(DLL)~程原理 http://www.aygfsteel.com/chalmers/archive/2011/03/31/347369.htmlq帆q帆Thu, 31 Mar 2011 03:35:00 GMThttp://www.aygfsteel.com/chalmers/archive/2011/03/31/347369.htmlhttp://www.aygfsteel.com/chalmers/comments/347369.htmlhttp://www.aygfsteel.com/chalmers/archive/2011/03/31/347369.html#Feedback0http://www.aygfsteel.com/chalmers/comments/commentRss/347369.htmlhttp://www.aygfsteel.com/chalmers/services/trackbacks/347369.html推荐比较大应用程序都由很多模块组成,q些模块分别完成相对独立的功能,它们彼此协作来完成整个Y件系l的工作。其中可能存在一些模块的功能较ؓ(f)通用Q在构造其它Y件系l时仍会(x)被用。在构造Y件系l时Q如果将所有模块的源代码都静态编译到整个应用E序EXE文g中,?x)生一些问题:(x)一个缺Ҏ(gu)增加了应用程序的大小Q它?x)占用更多的盘I间Q程序运行时也会(x)消耗较大的内存I间Q造成pȝ资源的浪费;另一个缺Ҏ(gu)Q在~写大的EXEE序Ӟ在每ơ修攚w建时都必调整编译所有源代码Q增加了~译q程的复杂性,也不利于阶段性的单元试?

  windows/" target=_blank>Windowspȝq_上提供了一U完全不同的较有效的~程和运行环境,你可以将独立的程序模块创Zؓ(f)较小的DLL(Dynamic Linkable Library)文gQƈ可对它们单独~译和测试。在q行Ӟ只有当EXEE序实要调用这些DLL模块的情况下Q系l才?x)将它们装蝲到内存空间中。这U方式不仅减了EXE文g的大和对内存空间的需求,而且使这些DLL模块可以同时被多个应用程序用。Microsoft Windows自己将一些主要的pȝ功能以DLL模块的Ş式实现。例如IE中的一些基本功能就是由DLL文g实现的,它可以被其它应用E序调用和集成?/p>

  一般来_(d)DLL是一U磁盘文Ӟ通常带有DLL扩展名)Q它由全局数据、服务函数和资源l成Q在q行时被pȝ加蝲到进E的虚拟I间中,成ؓ(f)调用q程的一部分。如果与其它DLL之间没有冲突Q该文g通常映射到进E虚拟空间的同一地址上。DLL模块中包含各U导出函敎ͼ用于向外界提供服务。Windows在加载DLL模块时将q程函数调用与DLL文g的导出函数相匚w?/p>

  在Win32环境中,每个q程都复制了自己的读/写全局变量。如果想要与其它q程׃n内存Q必M用内存映文件或者声明一个共享数据段。DLL模块需要的堆栈内存都是从运行进E的堆栈中分配出来的?/p>

  DLL现在来容易编写。Win32已经大大化了其编E模式,q有许多来自AppWizard和MFCcd的支持?/p>

  一、导出和导入函数的匹?/p>

  DLL文g中包含一个导出函数表。这些导出函数由它们的符号名和称为标识号的整C外界联系h。函数表中还包含了DLL中函数的地址。当应用E序加蝲DLL模块时时Q它q不知道调用函数的实际地址Q但它知道函数的W号名和标识受动态链接过E在加蝲的DLL模块时动态徏立一个函数调用与函数地址的对应表。如果重新编译和重徏DLL文gQƈ不需要修改应用程序,除非你改变了导出函数的符号名和参数序列?/p>

  单的DLL文g只ؓ(f)应用E序提供导出函数Q比较复杂的DLL文g除了提供导出函数以外Q还调用其它DLL文g中的函数。这P一个特D的DLL可以既有导入函数Q又有导入函数。这q不是一个问题,因ؓ(f)动态链接过E可以处理交叉相关的情况?/p>

  在DLL代码中,必须像下面这h声明导出函敎ͼ(x)

__declspec(dllexport) int MyFunction(int n);

  但也可以在模块定?DEF)文g中列出导出函敎ͼ不过q样做常常引h多的ȝ。在应用E序斚wQ要求像下面q样明确声明相应的输入函敎ͼ(x)

__declspec(dllimport) int MyFuncition(int n);

  仅有导入和导出声明ƈ不能使应用程序内部的函数调用链接到相应的DLL文g上。应用程序的目必须为链接程序指定所需的输入库QLIB文gQ。而且应用E序事实上必至包含一个对DLL函数的调用?/p>

  二、与DLL模块建立链接

  应用E序导入函数与DLL文g中的导出函数q行链接有两U方式:(x)隐式链接和显式链接。所谓的隐式链接是指在应用程序中不需指明DLL文g的实际存储\径,E序员不需兛_DLL文g的实际装载。而显式链接与此相反?/p>

  采用隐式链接方式Q程序员在徏立一个DLL文gӞ链接E序?x)自动生成一个与之对应的LIB导入文g。该文g包含了每一个DLL导出函数的符号名和可选的标识P但是q不含有实际的代码。LIB文g作ؓ(f)DLL的替代文件被~译到应用程序项目中。当E序员通过静态链接方式编译生成应用程序时Q应用程序中的调用函CLIB文g中导出符L(fng)匚wQ这些符h标识可入到生成的EXE文g中。LIB文g中也包含了对应的DLL文g名(但不是完全的路径名)Q链接程序将其存储在EXE文g内部。当应用E序q行q程中需要加载DLL文gӞW(xu)indowsҎ(gu)q些信息发现q加载DLLQ然后通过W号名或标识号实现对DLL函数的动态链接?/p>

  昑ּ链接方式对于集成化的开发语aQ例如VBQ比较适合。有了显式链接,E序员就不必再用导入文Ӟ而是直接调用Win32 的LoadLibary函数Qƈ指定DLL的\径作为参数。LoadLibaryq回HINSTANCE参数Q应用程序在调用GetProcAddress函数时用这一参数。GetProcAddress函数符号名或标识号转换为DLL内部的地址。假设有一个导出如下函数的DLL文gQ?/p>

extern "C" __declspec(dllexport) double SquareRoot(double d);

  下面是应用程序对该导出函数的昑ּ链接的例子:(x)

typedef double(SQRTPROC)(double);
HINSTANCE hInstance;
SQRTPROC* pFunction;
VERIFY(hInstance=::LoadLibrary("c:\\winnt\\system32\\mydll.dll"));
VERIFY(pFunction=(SQRTPROC*)::GetProcAddress(hInstance,"SquareRoot"));
double d=(*pFunction)(81.0);//调用该DLL函数

  在隐式链接方式中Q所有被应用E序调用的DLL文g都会(x)在应用程序EXE文g加蝲时被加蝲在到内存中;但如果采用显式链接方式,E序员可以决定DLL文g何时加蝲或不加蝲。显式链接在q行时决定加载哪个DLL文g。例如,可以一个带有字W串资源的DLL模块以英语加载,而另一个以西班牙语加蝲。应用程序在用户选择了合适的语种后再加蝲与之对应的DLL文g?/p>

  三、用符号名链接与标识号链接

  在Win16环境中,W号名链接效率较低,所有那时标识号链接是主要的链接方式。在Win32环境中,W号名链接的效率得到了改善。Microsoft现在推荐使用W号名链接。但在MFC库中的DLL版本仍然采用的是标识号链接。一个典型的MFCE序可能?x)链接到数百个MFC DLL函数上。采用标识号链接的应用程序的EXE文g体相对较?yu),因?f)它不必包含导入函数的长字W串W号名?br /> 比较大应用程序都由很多模块组成,q些模块分别完成相对独立的功能,它们彼此协作来完成整个Y件系l的工作。其中可能存在一些模块的功能较ؓ(f)通用Q在构造其它Y件系l时仍会(x)被用。在构造Y件系l时Q如果将所有模块的源代码都静态编译到整个应用E序EXE文g中,?x)生一些问题:(x)一个缺Ҏ(gu)增加了应用程序的大小Q它?x)占用更多的盘I间Q程序运行时也会(x)消耗较大的内存I间Q造成pȝ资源的浪费;另一个缺Ҏ(gu)Q在~写大的EXEE序Ӟ在每ơ修攚w建时都必调整编译所有源代码Q增加了~译q程的复杂性,也不利于阶段性的单元试?

  windows/" target=_blank>Windowspȝq_上提供了一U完全不同的较有效的~程和运行环境,你可以将独立的程序模块创Zؓ(f)较小的DLL(Dynamic Linkable Library)文gQƈ可对它们单独~译和测试。在q行Ӟ只有当EXEE序实要调用这些DLL模块的情况下Q系l才?x)将它们装蝲到内存空间中。这U方式不仅减了EXE文g的大和对内存空间的需求,而且使这些DLL模块可以同时被多个应用程序用。Microsoft Windows自己将一些主要的pȝ功能以DLL模块的Ş式实现。例如IE中的一些基本功能就是由DLL文g实现的,它可以被其它应用E序调用和集成?/p>

  一般来_(d)DLL是一U磁盘文Ӟ通常带有DLL扩展名)Q它由全局数据、服务函数和资源l成Q在q行时被pȝ加蝲到进E的虚拟I间中,成ؓ(f)调用q程的一部分。如果与其它DLL之间没有冲突Q该文g通常映射到进E虚拟空间的同一地址上。DLL模块中包含各U导出函敎ͼ用于向外界提供服务。Windows在加载DLL模块时将q程函数调用与DLL文g的导出函数相匚w?/p>

  在Win32环境中,每个q程都复制了自己的读/写全局变量。如果想要与其它q程׃n内存Q必M用内存映文件或者声明一个共享数据段。DLL模块需要的堆栈内存都是从运行进E的堆栈中分配出来的?/p>

  DLL现在来容易编写。Win32已经大大化了其编E模式,q有许多来自AppWizard和MFCcd的支持?/p>

  一、导出和导入函数的匹?/p>

  DLL文g中包含一个导出函数表。这些导出函数由它们的符号名和称为标识号的整C外界联系h。函数表中还包含了DLL中函数的地址。当应用E序加蝲DLL模块时时Q它q不知道调用函数的实际地址Q但它知道函数的W号名和标识受动态链接过E在加蝲的DLL模块时动态徏立一个函数调用与函数地址的对应表。如果重新编译和重徏DLL文gQƈ不需要修改应用程序,除非你改变了导出函数的符号名和参数序列?/p>

  单的DLL文g只ؓ(f)应用E序提供导出函数Q比较复杂的DLL文g除了提供导出函数以外Q还调用其它DLL文g中的函数。这P一个特D的DLL可以既有导入函数Q又有导入函数。这q不是一个问题,因ؓ(f)动态链接过E可以处理交叉相关的情况?/p>

  在DLL代码中,必须像下面这h声明导出函敎ͼ(x)

__declspec(dllexport) int MyFunction(int n);

  但也可以在模块定?DEF)文g中列出导出函敎ͼ不过q样做常常引h多的ȝ。在应用E序斚wQ要求像下面q样明确声明相应的输入函敎ͼ(x)

__declspec(dllimport) int MyFuncition(int n);

  仅有导入和导出声明ƈ不能使应用程序内部的函数调用链接到相应的DLL文g上。应用程序的目必须为链接程序指定所需的输入库QLIB文gQ。而且应用E序事实上必至包含一个对DLL函数的调用?/p>

  二、与DLL模块建立链接

  应用E序导入函数与DLL文g中的导出函数q行链接有两U方式:(x)隐式链接和显式链接。所谓的隐式链接是指在应用程序中不需指明DLL文g的实际存储\径,E序员不需兛_DLL文g的实际装载。而显式链接与此相反?/p>

  采用隐式链接方式Q程序员在徏立一个DLL文gӞ链接E序?x)自动生成一个与之对应的LIB导入文g。该文g包含了每一个DLL导出函数的符号名和可选的标识P但是q不含有实际的代码。LIB文g作ؓ(f)DLL的替代文件被~译到应用程序项目中。当E序员通过静态链接方式编译生成应用程序时Q应用程序中的调用函CLIB文g中导出符L(fng)匚wQ这些符h标识可入到生成的EXE文g中。LIB文g中也包含了对应的DLL文g名(但不是完全的路径名)Q链接程序将其存储在EXE文g内部。当应用E序q行q程中需要加载DLL文gӞW(xu)indowsҎ(gu)q些信息发现q加载DLLQ然后通过W号名或标识号实现对DLL函数的动态链接?/p>

  昑ּ链接方式对于集成化的开发语aQ例如VBQ比较适合。有了显式链接,E序员就不必再用导入文Ӟ而是直接调用Win32 的LoadLibary函数Qƈ指定DLL的\径作为参数。LoadLibaryq回HINSTANCE参数Q应用程序在调用GetProcAddress函数时用这一参数。GetProcAddress函数符号名或标识号转换为DLL内部的地址。假设有一个导出如下函数的DLL文gQ?/p>

extern "C" __declspec(dllexport) double SquareRoot(double d);

  下面是应用程序对该导出函数的昑ּ链接的例子:(x)

typedef double(SQRTPROC)(double);
HINSTANCE hInstance;
SQRTPROC* pFunction;
VERIFY(hInstance=::LoadLibrary("c:\\winnt\\system32\\mydll.dll"));
VERIFY(pFunction=(SQRTPROC*)::GetProcAddress(hInstance,"SquareRoot"));
double d=(*pFunction)(81.0);//调用该DLL函数

  在隐式链接方式中Q所有被应用E序调用的DLL文g都会(x)在应用程序EXE文g加蝲时被加蝲在到内存中;但如果采用显式链接方式,E序员可以决定DLL文g何时加蝲或不加蝲。显式链接在q行时决定加载哪个DLL文g。例如,可以一个带有字W串资源的DLL模块以英语加载,而另一个以西班牙语加蝲。应用程序在用户选择了合适的语种后再加蝲与之对应的DLL文g?/p>

  三、用符号名链接与标识号链接

  在Win16环境中,W号名链接效率较低,所有那时标识号链接是主要的链接方式。在Win32环境中,W号名链接的效率得到了改善。Microsoft现在推荐使用W号名链接。但在MFC库中的DLL版本仍然采用的是标识号链接。一个典型的MFCE序可能?x)链接到数百个MFC DLL函数上。采用标识号链接的应用程序的EXE文g体相对较?yu),因?f)它不必包含导入函数的长字W串W号名?br /> 四、编写DllMain函数

  DllMain函数是DLL模块的默认入口点。当windows/" target=_blank>Windows加蝲DLL模块时调用这一函数。系l首先调用全局对象的构造函敎ͼ然后调用全局函数DLLMain。DLLMain函数不仅在将DLL链接加蝲到进E时被调用,在DLL模块与进E分LQ以及其它时候)也被调用。下面是一个框架DLLMain函数的例子?/p>

HINSTANCE g_hInstance;
extern "C" int APIENTRY DllMain(HINSTANCE hInstance,DWORD dwReason,LPVOID lpReserved)
{
if(dwReason==DLL_PROCESS_ATTACH)
{
TRACE0("EX22A.DLL Initializing!\n");
//在这里进行初始化
}
else if(dwReason=DLL_PROCESS_DETACH)
{
TRACE0("EX22A.DLL Terminating!\n");
//在这里进行清除工?br /> }
return 1;//成功
}

  如果E序员没有ؓ(f)DLL模块~写一个DLLMain函数Q系l会(x)从其它运行库中引入一个不做Q何操作的~省DLLMain函数版本。在单个U程启动和终止时QDLLMain函数也被调用。正如由dwReason参数所表明的那栗?/p>

  五、模块句?/p>

  q程中的每个DLL模块被全局唯一?2字节的HINSTANCE句柄标识。进E自p有一个HINSTANCE句柄。所有这些模块句柄都只有在特定的q程内部有效Q它们代表了DLL或EXE模块在进E虚拟空间中的v始地址。在Win32中,HINSTANCE和HMODULE的值是相同的,q个两种cd可以替换使用。进E模块句柄几乎L{于0x400000Q而DLL模块的加载地址的缺省句柄是0x10000000。如果程序同时用了几个DLL模块Q每一个都?x)有不同的HINSTANCE倹{这是因为在创徏DLL文g时指定了不同的基地址Q或者是因ؓ(f)加蝲E序对DLL代码q行了重定位?br /> 模块句柄对于加蝲资源特别重要。Win32 的FindResource函数中带有一个HINSTANCE参数。EXE和DLL都有其自q资源。如果应用程序需要来自于DLL的资源,将此参数指定ؓ(f)DLL的模块句柄。如果需要EXE文g中包含的资源Q就指定EXE的模块句柄?/p>

  但是在用这些句柄之前存在一个问题,你怎样得到它们呢?如果需要得到EXE模块句柄Q调用带有Null参数的Win32函数GetModuleHandleQ如果需要DLL模块句柄Q就调用以DLL文g名ؓ(f)参数的Win32函数GetModuleHandle?/p>

  六、应用程序怎样扑ֈDLL文g

  如果应用E序使用LoadLibrary昑ּ链接Q那么在q个函数的参C可以指定DLL文g的完整\径。如果不指定路径Q或是进行隐式链接,W(xu)indows遵循下面的搜烦序来定位DLLQ?/p>

  1Q?包含EXE文g的目录,
  2Q?q程的当前工作目录,
  3Q?Windowspȝ目录Q?br />   4Q?Windows目录Q?br />   5Q?列在Path环境变量中的一pd目录?/p>

  q里有一个很Ҏ(gu)发生错误的陷阱。如果你使用VCQ+q行目开发,q且为DLL模块专门创徏了一个项目,然后生成的DLL文g拯到系l目录下Q从应用E序中调用DLL模块。到目前为止Q一切正常。接下来对DLL模块做了一些修改后重新生成了新的DLL文gQ但你忘记将新的DLL文g拯到系l目录下。下一ơ当你运行应用程序时Q它仍加载了老版本的DLL文gQ这可要当心Q?/p>

  七、调试DLLE序

  Microsoft 的VCQ+是开发和试DLL的有效工P只需从DLL目中运行调试程序即可。当你第一ơ这h作时Q调试程序会(x)向你询问EXE文g的\径。此后每ơ在调试E序中运行DLLӞ调试E序?x)自动加载该EXE文g。然后该EXE文g用上面的搜烦序列发现DLL文gQ这意味着你必设|Path环境变量让其包含DLL文g的磁盘\径,或者也可以DLL文g拯到搜索序列中的目录\径下?/p>

q帆 2011-03-31 11:35 发表评论
]]>
windows下进E和U程的关pR通信方式http://www.aygfsteel.com/chalmers/archive/2011/03/31/347358.htmlq帆q帆Thu, 31 Mar 2011 02:55:00 GMThttp://www.aygfsteel.com/chalmers/archive/2011/03/31/347358.htmlhttp://www.aygfsteel.com/chalmers/comments/347358.htmlhttp://www.aygfsteel.com/chalmers/archive/2011/03/31/347358.html#Feedback0http://www.aygfsteel.com/chalmers/comments/commentRss/347358.htmlhttp://www.aygfsteel.com/chalmers/services/trackbacks/347358.html

        q程是系l分配资源的单位Q每一个进E对应与一个活动的E序Q当q程ȀzLQ操作系l就系l的资源包括内存、I/O和CPU{分配给它,使它执行。线E是CPU分配旉的单位,每一个线E对应于它在q程中的一个函敎ͼ也就是内存中的代码段Q多个线E执行时CPU?x)根据它们的优先U分配时_(d)使它们完成自q功能?一般来_(d)q程中至一个线E,一个主U程和其他线E组成一个进E。多个线E的目的在于分nCPU的时间片Q从而完成ƈ行Q务?br /> 下面是自己整理的Q?br />  U程和进E的比较Q?br /> U程是比q程更小的能独立q行的基本单位,通常一个进E都有若q个U程Q至也需要一个线E?br />         1.调度
U程师调度和分派的基本单位,q程是资源拥有的基本单位?br />         2.q发?br /> q程之间可以q发执行Q在一个进E中的多个线E之间也可以q发执行?br />         3.拥有资源
q程是拥有资源的一个独立单元,U程自己不拥有系l资源(也有一Ҏ(gu)不可的资源Q但它可以访问其隶属q程的资源?br />         Q.pȝ开销
创徏或撤消进E时Q系l都要ؓ(f)之分配或回收资源Q如内存I间、I/O讑֤{,OS所付出的开销显著大于在创建或撤消U程时的开销Q进E切换的开销也远大于U程切换的开销?/p>

        q程是指在系l中正在q行的一个应用程序;U程是系l分配处理器旉资源的基本单元,或者说q程之内独立执行的一个单元。对于操作系l而言其调度单元是U程。一个进E至包括一个线E,通常该U程UCؓ(f)ȝE。一个进E从ȝE的执行开始进而创Z个或多个附加U程Q就是所谓基于多U程的多d?
  那进E与U程的区别到底是什么?q程是执行程序的实例。例如,当你q行C本程序(NodepadQ时Q你创Z一个用来容U组成Notepad.exe的代码及其所需调用动态链接库的进E。每个进E均q行在其专用且受保护的地址I间内。因此,如果你同时运行记事本的两个拷贝,该程序正在用的数据在各自实例中是彼此独立的。在C本的一个拷贝中无法看到该E序的第二个实例打开的数据?/p>

  以沙׃ؓ(f)例进行阐q。一个进E就好比一个沙。线E就如同沙箱中的孩子们。孩子们在沙子中跑来跑去,q且可能沙子攘到别的孩子眼中,他们?x)互相踢打或撕咬。但是,q些沙箱略有不同之处在于每个沙完全由墙壁
和顶封闭v来,无论׃的孩子如何狠命地攘沙Q他们也不会(x)影响到其它沙׃的其他孩子。因此,每个q程p一个被保护h的沙。未l许可,无h可以q出?/p>

  实际上线E运行而进E不q行。两个进E彼此获得专用数据或内存的唯一途径是通过协议来共享内存块。这是一U协作策略。下面让我们分析一下Q务管理器里的q程选项卡?/p>

  q里的进E是指一pdq程Q这些进E是由它们所q行的可执行E序实例来识别的Q这是q程选项卡中的第一列给Z映射名称的原因。请注意Q这里ƈ没有q程名称列。进Eƈ不拥有独立于其所归属实例的映名U。换a?br /> Q如果你q行5个记事本拯Q你会(x)看到5个称为Notepad.exe的进E。它们是如何彼此区别的呢Q其中一U方式是通过它们的进EIDQ因为每个进E都拥有其独一无二的编码。该q程ID由Windows NT或Windows 2000生成Qƈ可以循环使用。因此,q程ID不?x)越~越大,它们能够得到循环利用。第三列是被q程中的U程所占用的CPU旉癑ֈ比。它不是CPU的编P而是被进E占用的CPU旉癑ֈ比。此时我的系l基本上是空闲的。尽系l看上去每一U左右都只用一部分CPU旉Q但该系l空闲进E仍旧耗用了大U?9%的CPU旉?/p>

  W四列,CPU旉Q是CPU被进E中的线E篏计占用的时、分钟及U数。请注意Q我对进E中的线E用占用一词。这q不一定意味着那就是进E已耗用的CPU旉dQ因为,如我们一?x)儿看到的QNT计时的方式是Q当特定的时钟间隔激发时Q无恰y处于当前的线E中Q它都将计算到CPU周期之内。通常情况下,在大多数NTpȝ中,旉?0毫秒的间隔运行。每10毫秒NT的心脏就跛_一下。有一些驱动程序代码片D运行ƈ昄谁是当前的线E。让我们CPU旉的最?0毫秒记在它的帐上。因此,如果一个线E开始运行,q在持箋q行8毫秒后完成,接着Q第二个U程开始运行ƈ持箋?毫秒Q这Ӟ旉Ȁ发,L(fng)一猜这整整10毫秒的时钟周期到底记在了哪个U程的帐上?{案是第二个U程。因此,NT中存在一些固有的不准性,而NT恰是以这U方式进行计Ӟ实际情况也如是,大多?2位操作系l中都存在一个基于间隔的计时机制。请Cq一点,因ؓ(f)Q有时当你观察线E所耗用的CPUdӞ?x)出现尽该U程或许看上dq行q数十万ơ,但其CPU旉占用量却可能是零或非常短暂的现象Q那么,上述解释便是原因所在。上qC是我们在Q务管理器的进E选项卡中所能看到的基本信息列?br />



q帆 2011-03-31 10:55 发表评论
]]>
վ֩ģ壺 | Դ| | | | Ѿ| | | | ڳ| ղ| ¡| | ܿ| | Է| ͨ| | | | ͭ| ۩| ޻| | | Ƽ| ʳ| | ̶| | | ƽ| ű| | ¡| ǫ| ʲ| ʡ| | | ư|