vs2005 创建动态库及其调用方法

       又用到dll这个东东了,之前学的一知半解,参考了众多资料终于知道了一点皮毛,赶紧记下,以后都别忘了!吐舌头

       先介绍一下dll创建的方法,我目前知道的在vs2005 c++环境下有两种(不知道意外情况下是否存在第三种),大笑

      (1)利用 __declspec(export) 

           为了编写方面先预定义一下

#ifndef DLLTEST2_EXPORTS
#define DLLTEST2_EXPORTS
#endif

#ifdef DLLTEST2_EXPORTS
#define DLLTEST2_API  __declspec(dllexport)
#else
#define DLLTEST2_API __declspec(dllimport)
#endif
      然后在头文件中声明库函数,格式如下

     

DLLTEST2_API int MaxFun(int x,int y);
DLLTEST2_API int AddFun(int x,int y);
DLLTEST2_API void PrintFun(void);

     嘻嘻,又是这三个函数,浅显易懂啊! 另外说明一下,类似以下的内容自动生成的代码是给你做例子看的,直接注释掉,咱自己写就行 大笑

   

// 此类是从 dlltest2.dll 导出的
//class DLLTEST2_API Cdlltest2 {
//public:
//	Cdlltest2(void);
//	// TODO: 在此添加您的方法。
//};

//extern DLLTEST2_API int ndlltest2;

//DLLTEST2_API int fndlltest2(void);
//
然后编辑源文件,对声明的库函数进行定义

   

#include "stdafx.h"
#include "dlltest2.h"
#include <iostream>


#ifdef _MANAGED
#pragma managed(push, off)
#endif

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
					 )
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
	case DLL_THREAD_ATTACH:
	case DLL_THREAD_DETACH:
	case DLL_PROCESS_DETACH:
		break;
	}
    return TRUE;
}

#ifdef _MANAGED
#pragma managed(pop)
#endif

 这是导出变量的一个示例
//DLLTEST2_API int ndlltest2=0;
//
 这是导出函数的一个示例。
//DLLTEST2_API int fndlltest2(void)
//{
//	return 42;
//}

// 这是已导出类的构造函数。
// 有关类定义的信息,请参阅 dlltest2.h
//Cdlltest2::Cdlltest2()
//{
//	return;
//}


DLLTEST2_API int MaxFun(int x,int y)
{
	return ((x>y)?(x):(y));

}
DLLTEST2_API int AddFun(int x,int y)
{
	return (x+y);
}
DLLTEST2_API void PrintFun(void)
{
	std::cout<<"调用动态库函数"<<std::endl;
}

  点击编译就生成了我们想要的dll库了,看这里



下面说第二种方法:

(2)利用def文件

         声明函数、定义函数按照我们通常的做法写就可,如下所示:

         

int MaxFun(int x,int y);
 int AddFun(int x,int y);
 void PrintFun(void);
 

int MaxFun(int x,int y)
{
	return ((x>y)?(x):(y));

}
 int AddFun(int x,int y)
{
	return (x+y);
}
 void PrintFun(void)
{
	std::cout<<"调用动态库函数"<<std::endl;
}

创建编写def文件,

LIBRARY "dlltest2"
EXPORTS
  AddFun @1
  MaxFun @2
  PrintFun @3
  ;

dlltest2为动态库的库名,AddFun、MaxFun及PrintFun为导出的函数名,这个一看大家就知道怎么写了,需要说明的是,函数名和@之间的空格不能少,少了可就错了哦,我开始就犯了这样的错误,最后的分号,你当然也不能忽略。同样编译,我们的dll也出来了。

 创建过程就完了,有的说第一种方法导出时函数名会被改变,如果编译器不同导入时经常会出错,不知道真假,那我就建议大家用第二种方法咯微笑

下面我也唠叨下使用方法:

1)隐式链接

  把我们之前生成的dll、lib和头文件放到要调用的项目目录下,在我们调用的头文件前加上#pragma comment(lib,"dlltest2.lib"),就可以把那些库函数当项目中的函数一样自如调用了,有一个困惑也要注释一下,既然在dll项目中,dll和lib文件是在debug文件下,那我把dll和lib也放到调用项目的dubug文件夹下,应该没问题吧,头文件我放到与debug并行的dlltest2文件夹下,不知道问什么,找不到lib文件委屈,看清楚哦,是debug不是Debug哦,后来我把lib文件与头文件放到一起,就ok了,不知道是和我的路径设置有问题,还是别的原因,暂时也记下了。


2)显示调用

  这个说来就麻烦点,要利用LoadLibrary先加载动态库,再利用GetProcAdddress获取各函数的地址,使用完之后再用FreeLibrary释放,哎,不知道有没有说清楚,上代码吧吐舌头

#include "dlltest2.h"
#include <iostream>
#include <windows.h>
typedef int (*pAddFunc)(int,int);
typedef int (*pMaxFunc)(int ,int);
typedef void (*pPrintFun)(void);

int main(void)
{
	

	pAddFunc _AddFunc;
	pMaxFunc _MaxFunc;
	pPrintFun _PrintFun;

	HINSTANCE hInstance=LoadLibraryA("dlltest2.dll");
	if(hInstance==NULL)
	{
		FreeLibrary(hInstance);
	}
	_AddFunc=(pAddFunc)GetProcAddress(hInstance,"AddFun");
	_MaxFunc=(pMaxFunc)GetProcAddress(hInstance,"MaxFun");
	_PrintFun=(pPrintFun)GetProcAddress(hInstance,"PrintFun");
	if(_AddFunc==NULL||_MaxFunc==NULL||_PrintFun==NULL)
	{
		FreeLibrary(hInstance);//释放空间
	}

	_PrintFun();
	std::cout<<"输入20 25"<<std::endl;
	std::cout<<"AddFun"<<_AddFunc(20,25)<<std::endl;
	std::cout<<"MaxFun"<<_MaxFunc(20,25)<<std::endl;

	FreeLibrary(hInstance);
	return 0;

}

就知道这么多了,先到这里 大笑


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值