您的位置:首页 > 其它

SymbianDLL 学习总结(转载)

2011-08-06 10:53 239 查看
转载自:http://hi.baidu.com/david_jun/blog/item/05517f693f1a85ec421694d8.html

Symbian dll 开发总结
2011-05-08 16:09

SymbianDLL
学习总结
一、为什么需要dll?
1. 方便代码重用和移植,减少不必要的重复工作量
2. 可以有效地分离UI与engine,这样可以让UI与Engine同时进行开发,提高开发效率,也便于代码的维护
3. 可以节省手机内存,如果一个dll被多个程序使用的话,只需加载一份dll代码(仅限symbianOS)

二、dll的简要介绍
Symbian平台支持两种DLL,一种就是多态接口DLL(polymorphicinterface
DLL),另一种是静态接口DLL(staticinterface DLL)。

多态接口DLL只导出一个函数,通过他可以创建一个派生类的实例,然后可以调用其他函数,这个我们很少用到,不细说了(其实我也没仔细看),有兴趣的话可以参考SDK附带的例子:
C:\Symbian\9.1\S60_3rd_MR\Examples\Base\DLLs

静态接口DLL导出一系列函数,可以通过在工程中加入lib,直接调用这些函数,非常方便,这也是我们常用的一种。他的缺点就是静态加载,在主程序启动的时候就加载,不能在运行时加载(多态接口DLL在运行时加载),如果已发布并正在使用的接口要改动,用户程序只能重新编译。

下面的介绍只针对静态接口DLL,这个是我们开发常用到的!

三、如何使用?
每个dll必须包括两个同名的lib(导入库)文件和dll(实现)文件,才能使得其他程序使用该dll中的方法。

从ProjectExplorer中打开在一个工程的mmp文件,在LIBRARY页面上Add要使用的库文件,然后在使用文件中包含使用类的头文件即可。

四、如何编写一个dll?
1. 通过建立工程的向导(CarbideC/CIDE),生成一个DLL工程:
File->New->Symbian OS CProject->Basic Dynamically LinkedLibrary(DLL),然后输入工程名等,一路下一步就可以了。(有点奇怪,名字是BasicDynamically LinkedLibrary,实际却是static
interfacedll,不是吗?)

2. 在mmp文件里面加上EXPORTUNFROZEN,告诉编译器我们的dll还在开发中,随时
修改,这时编译工程(buildproject),就可以生成.lib/dll文件,这时就可以用其他的app或exe来测试你的lib/dll了。
对于要导出的函数,我们需要在声明文件(.h)中加上IMPORT_C前缀,在对应源文件(.cpp)中,加上EXPORT_C前缀,看起来像这样:
//.h文件
classCTestDll
:public CBase
{
public:
// new functions
IMPORT_Cstatic
CtecDll*NewL();
……
}
//.cpp文件
EXPORT_CCtecDll*
CtecDll::NewL()
{
CtecDll* self =CtecDll::NewLC();
CleanupStack::Pop(self);
return
self;
}

3.如果编写完成了,想发布你的dll,去掉mmp文件中的EXPORTUNFROZEN,然后Project->FreezeExports,
然后再编译工程(buildproject)一下,最终发布的dll/lib就生成了。
五、相关自动生成文件介绍
编写dll的过程中涉及到三个自动生成的文件,模块定义文件(.Def文件),导入库文件(.lib文件),实现文件(.dll):
1. 模块定义文件(.Def文件)
记录了DLL要导出的函数的信息,它是在执行FreezeExports操作后生成的,发布的lib文件将根据它的内容产生。该文件的主要作用就是为了保持DLL的向后的二进制兼容性(BinaryCompatibility)。
如何实现这种兼容性呢?在该文件中,我们可以看到系统为每个导出的接口分配一个序号,调用程序将根据这个序号来找到对应的函数实现,后加的接口只能在后面附加,序号连续递增,这样就不改变原来接口的序号。
.Def文件的看起来像这样:
EXPORTS
??1CMailEngine@@UAE@XZ @ 1 NONAME ;CMailEngine::~CMailEngine(void)
?GetMail@CMailEngine@@QAEHABVTDesC8@@@Z @
2 NONAME ; intCMailEngine::GetMail(class TDesC8 const&)

例如第二行:
GetMail:函数的名字
CMailEngine:所在类的名字
QAEHABVTDesC8:参数类型
2:该函数的序号

.Def文件存放的路径,我们可以从工程文件中看到:
//#if defined (WINS)
// DEFFILE..\bwins\projectName.def
//#elif defined (GCC32)
// DEFFILE..\bmarm\ projectName.def
//#else
// DEFFILE..\eabi\ projectName.def
//#endif

2. 导入库文件(.lib文件)
该文件描述了导出函数的详细信息,调用程序根据它来找到对应的函数,所以调用者需要把该文件加到自己工程中,否则就会出现“undefinedsymbol…”的错误。

3. 实现文件(.dll)
源码编译完的二进制文件,用户真正调用的文件

注:
.lib和.dll文件的默认生成路径(Debug版):
WINSCW: C:\Symbian\9.1\S60_3rd_MR\Epoc32\release\winscw\
GCCE: C:\Symbian\9.1\S60_3rd_MR\Epoc32\release\GCCE\UDEB

综上,以上文件生成的依赖关系如下:

依赖<-------------------------------------------

DLL <--- DEF <--- LIB 供外部使用
DLL
FAQ:
1. 我建了工程后,编译,生成了dll文件,却没有生成lib文件?
答:请确认mmp中,有没有添加EXPORTUNFROZEN,如果添加了,那就编辑下mmp文件,再编译下。还没有生成,那一定是你找错路径了!

2. 我在调用一个dll中的一个函数时,提示(undefinesymbol...)?
答:请确认mmp中,是否添加了.lib文件,如果是,请打开.lib文件(用记事本即可), 看看该函数是否生成。

3.我想在工程中,新添加一个类,然后再导出一些函数,该怎么办?
答:找到group->bld.inf打开,在Exportstab页上Add新添加类的头文件。

4. 我的Dll/Lib已经发布,用户正在使用,可是我需要修改一些接口,如接口的参数等,该怎么办?
答:祈祷这样的事情永远不要发生!除了让用户修改,重新编译程序,还不知道有什么好的办法。如果你找到了好的办法,一定要告诉我!

5. 如果已发布的dll我想在添加些接口,行吗
答:当然,这就是维护一个.Def文件意义,向后的二进制兼容。

6. dll可以有静态成员变量,或全局变量吗?
答:不可以!如果一定要呢?详细可以参考下面参考资料的[7][8]

7. 我遇到了一个问题,可是上面都没有提到,咋办呢?
答:仔细、耐心的看看错误信息或警告提示,往往答案就在那里面!如果还没有找到答案,那就baidu,google下吧!

参考资料:
[1] Series 60应用程序开发 Leigh Edwards RichardBarker,EMCC软件公司[著],周良忠[译]

[2] http://wiki.forum.nokia.com/index.php/How_to_generate_Import_Library_(.lib)
[3]http://developer.symbian.org/main/documentation/reference/s^3/doc_source/guide/EssentialIdioms/ExportandImportclasses.html

[4]http://developer.symbian.org/main/documentation/reference/s^3/doc_source/guide/EssentialIdioms/FrameworksLibsDlls.html

[5] http://blog.csdn.net/cheyiliu/archive/2009/10/14/4669233.aspx
[6] http://blog.csdn.net/yaloe/archive/2007/01/25/1492979.aspx
[7] http://blog.csdn.net/yaloe/archive/2007/01/25/1492986.aspx
[8]http://dev.csdn.net/article/78324.shtm

转自http://blog.csdn.net/sdy1978/archive/2010/01/27/5260871.aspx
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: