
c++中共有两种库:
1、LIB包含了函数所在的DLL文件和文件中函数位置的信息(入口),代码由运行时加载在进程空间中的DLL提供,称为动态链接库dynamic link library。(这种方式更灵活,写的程序体积小,但是需要exe和dll同时发布)
2、LIB包含函数代码本身,在编译时直接将代码加入程序当中,称为静态链接库static link library。(这种方式不是很灵活,因为lib被编译到exe中,写出的程序体积大,但是只需要发布exe即可,不需要dll文件)
共有两种链接方式:
1、动态链接使用动态链接库,允许可执行模块(dll文件或exe文件)仅包含在运行时定位DLL函数的可执行代码所需的信息。
2、静态链接使用静态链接库,链接器从静态链接库LIB获取所有被引用函数,并将库同代码一起放到可执行文件中。
关于lib和dll的区别如下:
(1)lib是编译时用到的,dll是运行时用到的。如果要完成源代码的编译,只需要lib;如果要使动态链接的程序运行起来,只需要dll。
(2)如果有dll文件,那么lib一般是一些索引信息,记录了dll中函数的入口和位置,dll中是函数的具体内容;如果只有lib文件,那么这个lib文件是静态编译出来的,索引和实现都在其中。使用静态编译的lib文件,在运行程序时不需要再挂动态库,缺点是导致应用程序比较大,而且失去了动态库的灵活性,发布新版本时要发布新的应用程序才行。
(3)动态链接的情况下,有两个文件:一个是LIB文件,一个是DLL文件。LIB包含被DLL导出的函数名称和位置,DLL包含实际的函数和数据,应用程序使用LIB文件链接到DLL文件。在应用程序的可执行文件中,存放的不是被调用的函数代码,而是DLL中相应函数代码的地址,从而节省了内存资源。DLL和LIB文件必须随应用程序一起发行,否则应用程序会产生错误。如果不想用lib文件或者没有lib文件,可以用WIN32 API函数LoadLibrary、GetProcAddress装载。
(静态连接)使用lib需注意两个文件:
(1)h头文件,包含lib中说明输出的类或符号原型或数据结构。应用程序调用lib时,需要将该文件包含入应用程序的源文件中。
(2)LIB文件,略。
(动态连接)使用dll需注意三个文件:
(1)h头文件,包含dll中说明输出的类或符号原型或数据结构的h文件。应用程序调用dll时,需要将该文件包含入应用程序的源文件中。
(2)LIB文件,是dll在编译、链接成功之后生成的文件,作用是当其他应用程序调用dll时,需要将该文件引入应用程序,否则产生错误。如果不想用lib文件或者没有lib文件,可以用WIN32API函数LoadLibrary、GetProcAddress装载。
(3)dll文件,真正的可执行文件,开发成功后的应用程序在发布时,只需要有exe文件和dll文件,并不需要lib文件和h头文件。
使用lib的方法:
静态lib中,一个lib文件实际上是任意个obj文件的集合,obj文件是cpp文件编译生成的。在编译这种静态库工程时,根本不会遇到链接错误;即使有错,也只会在使用这个lib的EXT文件或者DLL工程里暴露出来。
在VC中新建一个static library类型的工程Lib,加入testcpp文件和testh文件(头文件内包括函数声明),然后编译,就生成了Liblib文件。
别的工程要使用这个lib有两种方式:
(1)在project->link->Object/Library Module中加入Liblib文件(先查询工程目录,再查询系统Lib目录);或者在源代码中加入指令#pragma comment(lib, “Liblib”)。
(2)将Liblib拷入工程所在目录,或者执行文件生成的目录,或者系统Lib目录中。
(3)加入相应的头文件testh。
使用DLL的方法:
使用动态链接中的lib,不是obj文件的集合,即里面不会有实际的实现,它只是提供动态链接到DLL所需要的信息,这种lib可以在编译一个DLL工程时由编译器生成。
创建DLL工程的方法(略)。
(1)隐式链接
第一种方法是:通过project->link->Object/Library Module中加入lib文件(或者在源代码中加入指令#pragma comment(lib, “Liblib”)),并将dll文件置入工程所在目录,然后添加对应的h头文件。
#include "stdafxh"
#include "DLLSampleh"
#pragma comment(lib, "DLLSamplelib") //你也可以在项目属性中设置库的链接
int main()
{
TestDLL(123); //dll中的函数,在DllSampleh中声明
return(1);
}
(2)显式链接
需要函数指针和WIN32 API函数LoadLibrary、GetProcAddress装载,使用这种载入方法,不需要lib文件和h头文件,只需要dll文件即可(将dll文件置入工程目录中)。
#include <iostream>
#include <windowsh> //使用函数和某些特殊变量
typedef void (DLLFunc)(int);
int main()
{
DLLFunc dllFunc;
HINSTANCE hInstLibrary = LoadLibrary("DLLSampledll");
if (hInstLibrary == NULL)
{
FreeLibrary(hInstLibrary);
}
dllFunc = (DLLFunc)GetProcAddress(hInstLibrary, "TestDLL");
if (dllFunc == NULL)
{
FreeLibrary(hInstLibrary);
}
dllFunc(123);
std::cinget();
FreeLibrary(hInstLibrary);
return(1);
}
LoadLibrary函数利用一个名称作为参数,获得DLL的实例(HINSTANCE类型是实例的句柄),通常调用该函数后需要查看一下函数返回是否成功,如果不成功则返回NULL(句柄无效),此时调用函数FreeLibrary释放DLL获得的内存。
GetProcAddress函数利用DLL的句柄和函数的名称作为参数,返回相应的函数指针,同时必须使用强转;判断函数指针是否为NULL,如果是则调用函数FreeLibrary释放DLL获得的内存。此后,可以使用函数指针来调用实际的函数。
最后要记得使用FreeLibrary函数释放内存。
注意:应用程序如何找到DLL文件?
使用LoadLibrary显式链接,那么在函数的参数中可以指定DLL文件的完整路径;如果不指定路径,或者进行隐式链接,Windows将遵循下面的搜索顺序来定位DLL:
(1)包含EXE文件的目录
(2)工程目录
(3)Windows系统目录
(4)Windows目录
(5)列在Path环境变量中的一系列目录
// DllSample2h : Defines the export functions and classes
int _declspec(dllexport) Add(int a,int b);
void _declspec(dllexport) ShowString();
// DllSample2cpp : Defines the entry point for the DLL application
// Non-MFC DLLs的编写示例
// Non-MFC DLL:指的是不用MFC的类库结构,直接用C语言写的DLL,其输出
// 的函数一般用的是标准C接口,并能被非MFC或MFC编写的应用程序所调用
//
#include "DllSample2h"
#include "stdafxh"
/
这是一个输出函数的例子
在输出函数或类的申明中用到_declspec(dllexport),
这是VC提供的一个关键字,用它可在动态连接库中输出一个数据、
一个函数或一个类。用这个关键字可省不少事,不用在DEF文件
中说明要输出这个类、那个函数的
函数说明:略
参数说明:略
/
int _declspec(dllexport) Add(int a,int b)
{
return (a+b);
}
void _declspec(dllexport) ShowString()
{
printf("Nice to see you,I suceed!");
}
/
这是一个输出类的示例。
也用到了_declspec(dllexport)关键字
/
class _declspec(dllexport) Easy
{
// add your class definition here
// to avoid complexity,I omit the implementation here
/ // constructor and destructor
public:
Easy();
~Easy();
// data members
private:
int m_ID;
char m_Name[24];
// member functions
public:
char ToString();
char GetID();
int GetName();
/
};
/
函数说明:
每一个DLL必须有一个入口点,这就象我们用C编写的应用程序一样,
必须有一个WINMAIN函数一样。在这个示例中, DllMain是一个缺省的
入口函数,你不需要编写自己 的DLL入口函数,并用linker的命令行
的参数开关/ENTRY声明。用这个缺省的入口函数就能使动态连接库被
调用时得到正确的初始化
参数说明:
@hMoudle是动态库被调用时所传递来的一个指向自己的句柄
(实际上,它是指向_DGROUP段的一个选择符)
@ul_reason_for_call是一个说明动态库被调原因的标志。当进程或线程
装入或卸载动态连接库的时候, *** 作系统调用入口函数,并说明动态连接库
被调用的原因。它所有的可能值为:
DLL_PROCESS_ATTACH: 进程被调用
DLL_THREAD_ATTACH: 线程被调用
DLL_PROCESS_DETACH: 进程被停止
DLL_THREAD_DETACH: 线程被停止
@lpReserved是一个被系统所保留的参数。
/
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch( ul_reason_for_call )
{
case DLL_PROCESS_ATTACH:
// add your own hadling code here
break;
case DLL_THREAD_ATTACH:
// add your own hadling code here
break;
case DLL_THREAD_DETACH:
// add your own hadling code here
break;
case DLL_PROCESS_DETACH:
// add your own hadling code here
break;
}
return TRUE;
}
/
ps 调用DLL的方法:
(1)显式的调用
所谓显式的调用,是指在应用程序中用LoadLibrary或MFC提供的
AfxLoadLibrary显式的将自己所做的动态连接库调进来,动态连接库
的文件名即是上两函数的参数,再用GetProcAddress()获取想要引入
的函数。自此,你就可以象使用如同本应用程序自定义的函数一样来
调用此引入函数了。在应用程序退出之前,应该用FreeLibrary或
MFC提供的AfxFreeLibrary释放动态连接库。
(2)隐式的调用
隐式的调用则需要把产生动态连接库时产生的LIB文件加入到应
用程序的工程中,想使用DLL中的函数时,只须说明一下。隐式调
用不需要调用LoadLibrary()和FreeLibrary()
比较:由此看来,隐式说明调用的方法比较简单,但DLL改变后,应用程序
须重新编译。并且,所有被调用的DLL在应用程序加载的同时被加载到内
存中,但应用程序调用的DLL比较多时,装入的过程十分慢。隐式的调用
则在应用程序不知道所要装入的DLL,或显式调用不成功时,允许用户指定
所要加载的动态连接库,比较灵活
/
/
==================Associated MSDN Documents========================
Dynamically Loading and Invoking DLLs
GetProcAddress
/
--------------------------------------------------------------------------------------- 这是C#文件,希望使用Dll,API调用成功,但是我的Dll,:`(
// This's a Example of using vc DLL in C# environment
// Also the calling of WINDOWS API is displayed here
// basic prequisite
using System;
// this is required if you want to use DLL
using SystemRuntimeInteropServices;
// package the Apis in a class,haha
public class WinAPIImport
{
// this is the example of calling APIs in systematic DLLs
// just an example,don't mind the messy invokation
[DllImport("gdi32dll")]
static public extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
[DllImport("wsnmp32")] public static extern int SnmpCleanup();
[DllImport("dllsample2")] public static extern void ShowString();
[DllImport("dllsample2")] public static extern int Add(int a,int b);
}
namespace UsingDllSample00
{
/// <summary>
/// Class1 的摘要说明。
/// </summary>
class Class1
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] args)
{
// no need to create a WinAPIImport object to invoke extern funtions
// first, display the calling of Win32 API(s)
/1/ WinAPIImportSnmpCleanup();
// second, show how to use functions in
/2/ WinAPIImportAdd(2,3);
/3/ WinAPIImportShowString();
ConsoleWriteLine("Look,the functions in DLL are called!:)");
}
}
}
以上就是关于下面的delphi代码有点问题,恳请各位高手帮忙解决全部的内容,包括:下面的delphi代码有点问题,恳请各位高手帮忙解决、C# 怎么把其他应用程序集成到当前项目、windows中LIB和DLL的区别与使用等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)