VC动态库可以嵌套调用
来源:互联网 发布:淘宝分享赚怎么赚钱? 编辑:程序博客网 时间:2024/05/03 12:02
VC库编译的相关知识
一、动态库的调用方式
在VC中,依赖库分为静态库(.lib)和动态库(.dll)两种。如果使用的是静态库,会把依赖的静态库中的内容编译到目标文件中。如果是使用的是动态库,则根据引用方式进行编译。
动态库分为两部分:动态库静态链接(A.lib) 动态库(A.dll)。
动态库编译只需要在代码中包含动态库的头文件即可。
①动态库静态调用----隐式链接。
有两种方式 引用。
方式一:在工程属性中配置。
项目->属性->链接 设置附加库目录和“输入”选项中设置静态库链接(A.lib)
方式二:在代码中直接声明使用动态库链接。
项目->属性->链接 设置附加库目录
代码中添加
#pragma comment(lib, "A.lib")
链接器可以根据A.lib找到A.dll中相应的实现。
②动态库动态调用----显式链接。
通过Windows API LoadLiberary,通过GetProcAddress获取函数地址,然后调用。
这种方式不需要使用静态库链接(A.lib)
运行时需要将DLL和可执行文件放在同一目录。
二、VC动态库嵌套调用
VC动态库可以嵌套调用,当然最好是不进行嵌套调用。为了防止头文件嵌套包含,应该定义 #pragma once
例如:
动态库A的头文件 libA.h 定义:
#pragma once
#ifdef LIBA_EXPORTS
#define LIBA_API __declspec(dllexport)
#else
#define LIBA_API __declspec(dllimport)
#endif
#define PI_VALUE 3.1415926f
// 此类是从 libA.dll 导出的
class LIBA_API ClibA {
public:
ClibA(void);
// 计算圆锥体体积。
float TaperV(int r, int h);
//圆面积
float AreaCircle(int r);
};
extern LIBA_API int nlibA;
LIBA_API int fnlibA(void);
#ifndef LIBA_EXPORTS
# pragma comment(lib, "libA.lib")
#endif
//===========================
动态库libB 的头文件 libB.h的定义如下:
#pragma once
#ifdef LIBB_EXPORTS
#define LIBB_API __declspec(dllexport)
#else
#define LIBB_API __declspec(dllimport)
#endif
// 此类是从 libB.dll 导出的
class LIBB_API ClibB {
public:
ClibB(void);
// 圆柱体体积。
int ClinderV(int r, int h);
};
extern LIBB_API int nlibB;
LIBB_API int fnlibB(void);
#ifndef LIBB_EXPORTS
# pragma comment(lib, "libB.lib")
#endif
//==========================
libA.cpp
#include "stdafx.h"
#include "libA.h"
#include "libB.h"
// 这是导出变量的一个示例
LIBA_API int nlibA=0;
// 这是导出函数的一个示例。
LIBA_API int fnlibA(void)
{
return 42;
}
// 这是已导出类的构造函数。
// 有关类定义的信息,请参阅 libA.h
ClibA::ClibA()
{
return;
}
float ClibA::TaperV( int r, int h )
{
ClibB clibb;
return (float)clibb.ClinderV(r, h) / 3;
}
float ClibA::AreaCircle( int r )
{
return PI_VALUE * r * r;
}
成员函数TaperV需要调用libB的成员函数。
//==============================
libB.cpp
#include "stdafx.h"
#include "libB.h"
#include "libA.h"
// 这是导出变量的一个示例
LIBB_API int nlibB=0;
// 这是导出函数的一个示例。
LIBB_API int fnlibB(void)
{
return 42;
}
// 这是已导出类的构造函数。
// 有关类定义的信息,请参阅 libB.h
ClibB::ClibB()
{
return;
}
int ClibB::ClinderV( int r, int h )
{
ClibA cliba;
return cliba.AreaCircle(r) * h;
}
成员函数ClinderV需要调用libA的成员函数。
VC动态库相互嵌套并不会引起问题,但是最好不适用嵌套调用的方式。
在VC中,依赖库分为静态库(.lib)和动态库(.dll)两种。如果使用的是静态库,会把依赖的静态库中的内容编译到目标文件中。如果是使用的是动态库,则根据引用方式进行编译。
动态库分为两部分:动态库静态链接(A.lib) 动态库(A.dll)。
动态库编译只需要在代码中包含动态库的头文件即可。
①动态库静态调用----隐式链接。
有两种方式 引用。
方式一:在工程属性中配置。
项目->属性->链接 设置附加库目录和“输入”选项中设置静态库链接(A.lib)
方式二:在代码中直接声明使用动态库链接。
项目->属性->链接 设置附加库目录
代码中添加
#pragma comment(lib, "A.lib")
链接器可以根据A.lib找到A.dll中相应的实现。
②动态库动态调用----显式链接。
通过Windows API LoadLiberary,通过GetProcAddress获取函数地址,然后调用。
这种方式不需要使用静态库链接(A.lib)
运行时需要将DLL和可执行文件放在同一目录。
二、VC动态库嵌套调用
VC动态库可以嵌套调用,当然最好是不进行嵌套调用。为了防止头文件嵌套包含,应该定义 #pragma once
例如:
动态库A的头文件 libA.h 定义:
#pragma once
#ifdef LIBA_EXPORTS
#define LIBA_API __declspec(dllexport)
#else
#define LIBA_API __declspec(dllimport)
#endif
#define PI_VALUE 3.1415926f
// 此类是从 libA.dll 导出的
class LIBA_API ClibA {
public:
ClibA(void);
// 计算圆锥体体积。
float TaperV(int r, int h);
//圆面积
float AreaCircle(int r);
};
extern LIBA_API int nlibA;
LIBA_API int fnlibA(void);
#ifndef LIBA_EXPORTS
# pragma comment(lib, "libA.lib")
#endif
//===========================
动态库libB 的头文件 libB.h的定义如下:
#pragma once
#ifdef LIBB_EXPORTS
#define LIBB_API __declspec(dllexport)
#else
#define LIBB_API __declspec(dllimport)
#endif
// 此类是从 libB.dll 导出的
class LIBB_API ClibB {
public:
ClibB(void);
// 圆柱体体积。
int ClinderV(int r, int h);
};
extern LIBB_API int nlibB;
LIBB_API int fnlibB(void);
#ifndef LIBB_EXPORTS
# pragma comment(lib, "libB.lib")
#endif
//==========================
libA.cpp
#include "stdafx.h"
#include "libA.h"
#include "libB.h"
// 这是导出变量的一个示例
LIBA_API int nlibA=0;
// 这是导出函数的一个示例。
LIBA_API int fnlibA(void)
{
return 42;
}
// 这是已导出类的构造函数。
// 有关类定义的信息,请参阅 libA.h
ClibA::ClibA()
{
return;
}
float ClibA::TaperV( int r, int h )
{
ClibB clibb;
return (float)clibb.ClinderV(r, h) / 3;
}
float ClibA::AreaCircle( int r )
{
return PI_VALUE * r * r;
}
成员函数TaperV需要调用libB的成员函数。
//==============================
libB.cpp
#include "stdafx.h"
#include "libB.h"
#include "libA.h"
// 这是导出变量的一个示例
LIBB_API int nlibB=0;
// 这是导出函数的一个示例。
LIBB_API int fnlibB(void)
{
return 42;
}
// 这是已导出类的构造函数。
// 有关类定义的信息,请参阅 libB.h
ClibB::ClibB()
{
return;
}
int ClibB::ClinderV( int r, int h )
{
ClibA cliba;
return cliba.AreaCircle(r) * h;
}
成员函数ClinderV需要调用libA的成员函数。
VC动态库相互嵌套并不会引起问题,但是最好不适用嵌套调用的方式。
首先理解了三个概念:
1. 静态链接库
这是一个名词,是.lib库。
2. 静态链接
在工程设置的Link项中,添加所要链接的.lib库,程序中包含其导出函数对应的头文件。再编译时,就会将使用到的静态库中的函数一同编译到目标文件中,目标文件可以是lib库,dll,exe,ocx等。
3. 动态链接
程序再运行时才装载要使用的函数。动态链接一般都是使用Dll——动态链接库。
一直都是使用动态库,经常是动态库链接一个静态库。最近想使用静态库链接一个静态库,可能要好几层,同事们都说不可以,可我觉得理论上没有问题,于是就试验了一下,事实证明是完全可以的。
1. 在VC6.0上,lib库的工程设置中,是没有追加静态库的地方的,只能再程序中使用语句#pragma comment(lib, "***.lib")来追加。
2. 在VS2005上,我使用的是VS2005,它的工程设置中,依然可以追加依赖的静态库。
在使用方式上没有什么特殊之处。
- VC动态库可以嵌套调用
- vc 调用动态库
- VC++调用C#动态库
- VC动态库调用方法
- 在VC++中隐式调用动态链接库
- VC调用matlab生成的动态库
- VC中调用动态库文件Dll
- VC++创建和调用动态库
- c#与vc调用动态链接库
- VC调用动态链接库的错误
- VC++动态库DLL制作和调用
- LR调用VC++6.0动态链接库
- VC++:创建,调用Win32动态链接库
- VC动态调用DLL
- VC动态调用DLL
- linux .so动态库makefile的嵌套调用
- VC 动态调用DLL接口
- 习语言可以实现动态链接库调用了
- boot in and jack up
- PsExec - Windows Sysinternals
- build android
- linux kernel 2.4与kernel2.6的区别
- LeetCode之Best Time to Buy and Sell Stock III
- VC动态库可以嵌套调用
- SQLite一条SQL语句插入多条记录
- ROC
- Linux几种内核镜像及其关系
- erlang 格式化输出
- matlab无向图 有向图画法
- DIV+CSS学习
- flot API(中文版)
- sql之left join、right join、inner join和逗号的区别