跨平台C++动态连接库的实现

我对与solaris ,hp ,Windows 这三个平台的动态库的实现,进行了探索,对于soloaris,hp等Unix 平台来讲,主要是make文件的制作,而Windows 下还需要对类头进行修饰.

  本列主要实现了一个动态库和一个调用动态库的运行程序,动态库包括mytime.h ,mytime.cpp , 在windows下还需要dllt1.cpp ,这个包含动态库的DllMain入口函数,

  StdAfx.cpp ,stdAfx.h是与预编译相关的文件. 运行程序包括dy.cpp 包括对动态库的调用。

  下面先谈Unix下的编译指令.

  一. hp平台下

  在hp下使用hp自带的aCC编译器

rm *.o
rm *.sl
aCC +z mytime.cpp //+z生成动态库需要的*.o文件

aCC -b -o libmy.sl mytime.o //-b生成动态库 ,-o libmy.sl 表示生成动态库的名称为libmy.sl
aCC dy.cpp libmy.sl //用dy.cpp libmy.sl生成可执行程序,默认为a.out,也可以用 –o指定名称

  二. solaris平台下

  在soloaris下用workshop带的 CC .

CC -c mytime.cpp //-c 生成动态库需要的*.o文件
CC -G -o libmy.so mytime.o ////-b生成动态库,名称为libmy.so
CC -Bdynamic -o myee libmy.so dy.cpp //生成可执行程序myee

ln -s /export/home/hurh/tdll/libmy.so /lib // solaris下在运行前要用root用户配置动态库libmy.so

  下面再谈谈Windows下的动态库需要考虑的问题,用VC编译。

  主要谈动态库头文件mytime.h 的声明

#ifndef MYTIME_H
#define MYTIME_H

#ifndef WIN32
  #define DLLT_API __declspec(dllexport)
#else
  #ifdef JESTERDLL
  #define DLLT_API __declspec(dllexport)
  #else
  #define DLLT_API __declspec(dllimport)
  #pragma comment(lib, "dllt1.lib")
  #endif
#endif

struct DATETYPE
{
  int year;
  int mon;
  int day;
};

struct TIMETYPE
{
  char hour;
  char min;
  char sec;
};

int DLLT_API getdate(DATETYPE *d);
int DLLT_API gettime(TIMETYPE *t);

class DLLT_API gqlass{
  public:
  int ineid;
  void setneid(int neid);
  gqlass();
  ~gqlass();
};

#endif

  宏WIN32, JESTERDLL 需要在动态库编译中用指令 –D 指定。 对于动态库需要导出的类或函数需要用修饰__declspec(dllexport),而对于引用程序需要用__declspec(dllimport) 修饰,这就是我们联合WIN32, JESTERDLL所达到的目的, 动态库的名称为dllt1.dll 如果有了 #pragma comment(lib, "dllt1.lib") 就不需要在make文件指定需要连接dllt1库了.

  附部分源代码:

//mytime.cpp
#include"stdafx.h"
#include "time.h"
#include "mytime.h"

int getdate(DATETYPE *d)
{
  long ti;
  struct tm *tm;
  time(&ti);
  tm=localtime(&ti);
  d->year=tm->tm_year+1900;
  d->mon=tm->tm_mon+1;
  d->day=tm->tm_mday;
  return 0;
}

int gettime(TIMETYPE *t)
{
  long ti;
  struct tm *tm;
  time(&ti);
  tm=localtime(&ti);
  t->hour=tm->tm_hour;
  t->min=tm->tm_min;
  t->sec=tm->tm_sec;
  return 0;
}
gqlass::gqlass()
{
  ineid=0;
}
gqlass::~gqlass()
{

}

void gqlass::setneid(int neid)
{
  ineid=neid;
}

//dy.cpp

#include"stdafx.h"
#include "stdio.h"
#include "../dllt1/mytime.h"
int main()
{
  DATETYPE d;
  TIMETYPE t;
  void *dp;
  char *error;

  puts("动态链接库应用示范");

  getdate(&d); /* 调用此共享函数 */
  printf("当前日期: %04d-%02d-%02d\n",d.year,d.mon,d.day);

  gettime(&t); /* 调用此共享函数 */
  printf("当前时间: %02d:%02d:%02d\n",t.hour,t.min,t.sec);
  gqlass gq;
  printf("before setneid gq.ineid=%d\n",gq.ineid);
  gq.setneid(123);
  printf("after setneid gq.ineid=%d\n",gq.ineid);

  return 0;
}


(文/foolpanda1168  出处/Blog)

 感谢原创者的辛勤劳动,希望对您有所帮助,转载请注明原出处。
 您可能对 [C & C++] 的这些文章也感兴趣:

在C++中创建并使用Web服务
开发精彩实例:窗体自动隐藏
C语言程序设计基础之文件
C++数据结构学习:在链表中链入对象
C++数据结构学习:二叉树(2)
C++学习:在C++中创建持久对象
C++ 中重载 + 操作符的正确方法
C/C++中枚举类型(enum)
经典:教你理解复杂的C/C++声明
如何用C++编程获得某台机器的IP地址