ACE DLL接口实现以及调用(普通函数和类接口函数)

来源:互联网 发布:linux io 编辑:程序博客网 时间:2024/05/16 01:13


最近深深感受到掌握一种新的知识时,写成博客很重要。第一可以加深印象,第二可以提高自己的编写能力,第三可以整理自己的思路,第四以后忘记时可以第一时间浏览自己的博客。这是小弟第一个博客,有什么不足的地方,欢迎指正。谢谢。


最近需要将网络通信接口封装成DLL的形式,又需要跨平台,选择的第三方库是:ACE。

ACE有自己的一套加载DLL方法,下面开始一一讲解。


分2点讲解ACE 中DLL的编写和调用。


第一点:普通接口函数。

eg:

///////   test.h  //////

#include "ace/svc_export.h"       //  用到ACE_Svc_Export时需要包含此头文件。

// 头文件中定义接口函数

extern "C" ACE_Svc_Export int func();


/////   test.cpp   ///////

// cpp中实现此函数

int func()
{
    return 123456;
}


注意点

#if defined(_WIN32)
    #ifdef DLL_PROJECT_EXPORTS
    #define START_API __declspec(dllexport)
    #else
    #define START_API __declspec(dllimport)
    #endif
#endif

#if  defined(__linux)
    #define  START_API
#endif

// 提供接口

extern "C" START_API bool Send(const void* msg, unsigned int len, unsigned long ulTimeout);

这是之前使用的方法,这是WINDOWS下的一套方法,这种形式也可以。但是ACE已经提供了一种很方便很简洁的方法,就是刚说提到的那样。


将test工程编译成DLL。


下面讲解使用以上编译的DLL。

调用时包含上面的接口头文件,以及将上面的DLL复制到当前目录进行使用。

/////  main.cpp  /////

#include "test.h"


//  使用ACE_DLL需要包含的头文件

#include "ace/DLL.h"
#include "ace/OS.h"

#include "ace/Auto_Ptr.h"


// 声明DLL接口

typedef int (*test)();


int main()

{


    // 打开dll

ACE_DLL dll;
    int retval = dll.open(ACE_DLL_PREFIX ACE_TEXT("test"));//dll file name  注意:不需要后缀名
    if (retval != 0)   
    {   
        ACE_ERROR_RETURN ((LM_ERROR, "%p", "dll.open"), -1);
    }



void *vInfo = dll.symbol (ACE_TEXT ("func"));  // export name

    ptrdiff_t ptrInfo = reinterpret_cast<ptrdiff_t> (vInfo);
    test tt = reinterpret_cast<test> (ptrInfo);

    if (tt == 0)
    {
        return -1;
    }

   // 此处就可以调用dll中的函数了

    int res = tt();

return 0;

}



第二点:类接口函数

// test.h ////

class base

{

    public:

          virtual int func() = 0;

};

class device : public base

{

    public:

         int func();

};


// 接口声明

extern "C" ACE_Svc_Export base* Create(void);


// test.cpp ///

int device::func()

{

     return 123456;

}


写到这里有人会觉得奇怪,为什么要提供一个base纯虚接口类呢。

不提供纯虚函数接口类无法编译。我也是查找各种资料明白的。具体为什么欢迎讨论。


用法和上面写的一样,只有一点需要注意。

// main.cpp ///

// 包含头文件


typedef base* (*factory)();


int main()

{

// open

// .....

void *vInfo = dll.symbol (ACE_TEXT ("Create"));  // export name  //dll中接口名

    ptrdiff_t ptrInfo = reinterpret_cast<ptrdiff_t> (vInfo);
    factory tt = reinterpret_cast<factory> (ptrInfo);

    if (tt == 0)
    {
        return -1;
    }

    //  接口类函数注意点。

    auto_ptr<device> ptr(tt()); // 注意:tt函数括号 

   // 成功调用dll中的接口放回123456.

   int result =   ptr->func();

return 0;

}


that's all。  谢谢大家。

0 0
原创粉丝点击