VS 动态库的静态调用以及动态调用

时间:2024-03-19 14:38:50

VS 动态库的静态调用以及动态调用

动态库的建立

VS 动态库的静态调用以及动态调用

  • MyMath.h
#pragma once

extern "C" __declspec(dllexport) int add(int x, int y);
  • MyMath.cpp
#include "MyMath.h"

int add(int x, int y)
{
	return x + y;
}

编译生成动态库,产生dll文件,lib文件,此处lib文件是导入库。(PS:lib文件分为导入库和静态链接库)

  • 为什么要加 extern “C”
    加上extern “C” 会以C编译器的方式去命名导出函数名! 用depends工具可以看出区别

百度云链接:depends 提取码:acox
读者可以自行测试,加extern "C"生成的dll与不加生成的dll,在工具中的符号

动态库的静态调用

将动态库头文件MyMath.h添加到测试程序中,并将.lib文件以及.dll文件拷贝至测试程序的Debug目录下。

#include <iostream>
#include "MyMath.h"
#include <windows.h>
using namespace std;

#pragma comment(lib,"F:/SVN/MyDll/Debug/MyDll.lib")

int _tmain(int argc, _TCHAR* argv[])
{
	int t = add(2, 3);
	cout << t << endl;
	getchar();
	return 0;
}

此处.lib文件为导入库,而并非静态链接库,其实际的执行代码位于动态库中,导入库只包含了地址符号表等,确保程序找到对应函数的一些基本地址信息。

动态库的动态调用

只需要一个.dll文件即可完成动态调用。

#include <windows.h>
#include <iostream>
using namespace std;
typedef int(*Add)(int, int);
int main()
{
	HINSTANCE hIn = NULL;
	hIn = LoadLibrary(_T("F:/SVN/MyDll/Debug/MyDll.dll"));

	if (hIn == INVALID_HANDLE_VALUE)
	{
		cout << "Load DLL error" << endl;
		return -1;
	}

	Add pFun = NULL;
	pFun = (Add)GetProcAddress(hIn, "add"); 
	int i = pFun(2, 4);
	cout << "pFun(2, 4) = " << i << endl;
	
	FreeLibrary(hIn);
    return 0;
}