Symbian DLL 学习总结

来源:互联网 发布:部落冲突黄毛升级数据 编辑:程序博客网 时间:2024/05/22 17:22

                               Symbian DLL 学习总结

一、为什么需要dll

1.       方便代码重用和移植,减少不必要的重复工作量

2.       可以有效地分离UIengine,这样可以让UIEngine同时进行开发,提高开发效率,也便于代码的维护

3.       可以节省手机内存,如果一个dll被多个程序使用的话,只需加载一份dll代码(仅限symbianOS

 

二、dll的简要介绍

   Symbian平台支持两种DLL,一种就是多态接口DLLpolymorphic interface DLL),另一种是静态接口DLLstatic interface DLL)。

 

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

C:/Symbian/9.1/S60_3rd_MR/Examples/Base/DLLs

 

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

 

 

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

 

三、如何使用?

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

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

 

四、如何编写一个dll

 1.  通过建立工程的向导(Carbide C/C++ IDE),生成一个DLL工程:

   File->New->Symbian OS C++ Project->Basic Dynamically Linked Library(DLL),然后输入工程名等,一路下一步就可以了。(有点奇怪,名字是Basic Dynamically Linked Library,实际却是static interface dll,不是吗?)

 

2.        mmp文件里面加上EXPORTUNFROZEN,告诉编译器我们的dll还在开发中,随时

修改,这时编译工程(build project),就可以生成.lib/dll文件,这时就可以用其他的appexe来测试你的lib/dll了。

对于要导出的函数,我们需要在声明文件(.h)中加上IMPORT_C 前缀,在对应源文件(.cpp)中,加上EXPORT_C前缀,看起来像这样:

//.h 文件

class CTestDll : public CBase

    { 

public:

    // new functions

    IMPORT_C static CtecDll* NewL();

……

}

//.cpp文件

EXPORT_C CtecDll* CtecDll::NewL()

    {

    CtecDll* self = CtecDll::NewLC();

    CleanupStack::Pop(self);

    return self;

    }

 

3. 如果编写完成了,想发布你的dll,去掉mmp文件中的EXPORTUNFROZEN,然后Project->Freeze Exports, 然后再编译工程(build project)一下,最终发布的dll/lib就生成了。

 

以上就是写一个dll的大概过程,如果一切顺利,就无需往下看了!

 

五、相关自动生成文件介绍

   编写dll的过程中涉及到三个自动生成的文件,模块定义文件(.Def文件),导入库文件(.lib文件),实现文件(.dll):

1.  模块定义文件(.Def文件)

   记录了DLL要导出的函数的信息,它是在执行Freeze Exports操作后生成的,发布的lib文件将根据它的内容产生。该文件的主要作用就是为了保持DLL的向后的二进制兼容性(Binary Compatibility)。

如何实现这种兼容性呢?在该文件中,我们可以看到系统为每个导出的接口分配一个序号,调用程序将根据这个序号来找到对应的函数实现,后加的接口只能在后面附加,序号连续递增,这样就不改变原来接口的序号。

.Def文件的看起来像这样:

EXPORTS

    ??1CMailEngine@@UAE@XZ @ 1 NONAME ; CMailEngine::~CMailEngine(void)

    ?GetMail@CMailEngine@@QAEHABVTDesC8@@@Z @ 2 NONAME ; int CMailEngine::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文件)

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

 

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中的一个函数时,提示(undefine symbol...?

     答:请确认mmp中,是否添加了.lib文件,如果是,请打开.lib文件(用记事本即可),  看看该函数是否生成。

 

3. 我想在工程中,新添加一个类,然后再导出一些函数,该怎么办?

  答:找到group->bld.inf打开,在Exports tab页上Add新添加类的头文件。

 

4.       我的Dll/Lib已经发布,用户正在使用,可是我需要修改一些接口,如接口的参数等,该怎么办?

答:祈祷这样的事情永远不要发生!除了让用户修改,重新编译程序,还不知道有什么好的办法。如果你找到了好的办法,一定要告诉我!

 

5.       如果已发布的dll我想在添加些接口,行吗

  答:当然,这就是维护一个 .Def文件意义,向后的二进制兼容。

 

6.       dll可以有静态成员变量,或全局变量吗?

答:不可以!如果一定要呢?详细可以参考下面参考资料的[7][8]

7.       我遇到了一个问题,可是上面都没有提到,咋办呢?

  答:仔细、耐心的看看错误信息或警告提示,往往答案就在那里面!如果还没有找到答案,那就baidugoogle下吧!

 

参考资料:

[1] Series 60 应用程序开发  Leigh Edwards Richard BarkerEMCC软件公司[],周良忠[]

 

[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