Windows命令加载动态库

在读TNN/MACE代码时总看到动态加载相关代码,因此在这做一个总结和试用。代码参考windows动态加载和linux动态加载

通过dlsym/getprocaddress获取动态库的函数地址,然后利用该地址进行其它相关操作(重命名函数之类的)。

#ifdef WIN32
#include <windows.h>
#else
#include <dlfcn.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include "CL/cl.h"

typedef CL_API_ENTRY cl_int(CL_API_CALL *clGetPlatformIDsFuncPtr)(
	cl_uint          /* num_entries */,
	cl_platform_id * /* platforms */,
	cl_uint *        /* num_platforms */) CL_API_SUFFIX__VERSION_1_0;
typedef CL_API_ENTRY cl_int(CL_API_CALL *clGetPlatformInfoFuncPtr)(
	cl_platform_id   /* platform */,
	cl_platform_info /* param_name */,
	size_t           /* param_value_size */,
	void *           /* param_value */,
	size_t *         /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
static clGetPlatformIDsFuncPtr clGetPlatformIDsPtr = NULL;
static clGetPlatformInfoFuncPtr clGetPlatformInfoPtr = NULL;

#define clGetPlatformInfo clGetPlatformInfo_Test
cl_int CL_API_CALL clGetPlatformInfo_Test(
	cl_platform_id   platform,
	cl_platform_info param_name,
	size_t           param_value_size,
	void             *param_value,
	size_t           *param_value_size_ret)
{
	return (clGetPlatformInfoPtr)(platform, param_name, param_value_size, param_value, param_value_size_ret);
}
int main()
{
#ifdef WIN32
	HINSTANCE ocl_lib = LoadLibrary(TEXT("opencl.dll"));
	if (!ocl_lib)
	{
		printf("Load Library failed\n");
	}
	clGetPlatformIDsPtr = (clGetPlatformIDsFuncPtr)(GetProcAddress(ocl_lib, "clGetPlatformIDs"));
	clGetPlatformInfoPtr = (clGetPlatformInfoFuncPtr)(GetProcAddress(ocl_lib, "clGetPlatformInfo"));
#else
	void* ocl_lib = dlopen("libOpenCL.so", RTLD_NOW);
	if (!ocl_lib)
	{
		printf("Load Library failed\n");
	}
	clGetPlatformIDsPtr = (clGetPlatformIDsFuncPtr)(dlsym(ocl_lib, "clGetPlatformIDs"));
	clGetPlatformInfoPtr = (clGetPlatformInfoFuncPtr)(dlsym(ocl_lib, "clGetPlatformInfo"));
#endif

	unsigned int num = 0;
	int iRslt = clGetPlatformIDsPtr(0, NULL, &num);

	cl_platform_id* platform_id = (cl_platform_id*)malloc(num * sizeof(cl_platform_id));

	iRslt = clGetPlatformIDsPtr(num, platform_id, NULL);

	cl_platform_id cl_platform = platform_id[0];
	free(platform_id);
	char platname[50];
	clGetPlatformInfo(cl_platform, CL_PLATFORM_NAME, 50 * sizeof(char),
		platname, NULL);
#ifdef WIN32
	FreeLibrary(ocl_lib);
#else
	dlclose(ocl_lib);
#endif
	printf("%s\n", platname);
	return iRslt;
}

Windows动态链接库DLL
1.什么是DLL
DLL,即动态链接库,是包含若干个函数的库文件,可供其他程序运行时调用。

2.DLL的优缺点
优点:代码重用,可供多个程序同时调用

缺点:易发生版本冲突
当新版本的动态链接库不兼容旧版本时,其他使用该DLL的程序可能无法正常工作。
针对这一问题,我们需要在程序中加上一个manifest文件,指明该程序所使用的DLL版本号。
此时,程序将根据manifest加载指定版本的DLL,否则按默认版本加载。

3.关于LIB和DLL
LIB,是静态链接库,分为静态lib和动态lib。
静态lib:包含函数代码声明和实现,编译后所有代码都嵌入到宿主程序中。不需要再另行调用DLL。
动态lib:相当于一个.h头文件,它是对实现部分(.DLL)的导出部分的声明。编译后宿主程序也只包括声明部分。运行时需调用相应的DLL文件。

 1 #ifndef _MYMATH_H
 2 #define _MYMATH_H
 3 #include <stdio.h>
 4 
 5 
 6 #ifdef MYMATHDLL_EXPORT 
 7 #define MYMATHDLL_API _declspec(dllexport)
 8 #else
 9 #define MYMATHDLL_API _declspec(dllimport)
10 #endif // end of MYMATHDLL_EXPORT
11 
12 #ifdef __cplusplus
13 extern "C" {
14 #endif // end of __cplusplus
15 
16 int MYMATHDLL_API Add(int a, int b);
17 
18 int MYMATHDLL_API Sub(int a, int b);
19 
20 int MYMATHDLL_API Mul(int a, int b);
21 
22 int MYMATHDLL_API Div(int a, int b);
23 
24 #ifdef __cplusplus
25 }
26 #endif // end of __cplusplus
27 
28 
29 
30 #endif// end of _MYMATH_H
 1 #include "stdafx.h"
 2 
 3 #define MYMATHDLL_EXPORT
 4 #include "MyMath.h"
 5 #include <stdio.h>
 6 
 7 
 8 
 9 int Add(int a, int b)
10 {
11     printf("Call %s
", __FUNCTION__);
12     return a + b;
13 }
14 
15 int Sub(int a, int b)
16 {
17     printf("Call %s
", __FUNCTION__);
18     return a - b;
19 }
20 
21 int Sub(int a, int b, int c)
22 {
23     return a + b + c;
24 }
25 
26 int Mul(int a, int b)
27 {
28     printf("Call %s
", __FUNCTION__);
29     return a * b;
30 }
31 
32 int Div(int a, int b)
33 {
34     printf("Call %s
", __FUNCTION__);
35     return a / b;
36 }

main

 1 #include <iostream>
 2 #include <Windows.h>
 3 
 4 #include "MyMath.h"
 5 #pragma comment(lib, "DllTest.lib")
 6 
 7 void ExplicitCall();
 8 void ImplicitCall();
 9 
10 int main()
11 {
12     std::cout << "Hello World!
"; 
13     ImplicitCall();
14     //ExplicitCall();
15     return 0;
16 }
17 
18 void ExplicitCall()
19 {
20     typedef int(*pAdd)(int a, int b);
21 
22     typedef int(*pSub)(int a, int b);
23 
24     HINSTANCE hDll = NULL;
25     pAdd _Add = NULL;
26     pSub _Sub = NULL;
27 
28 
29     hDll = LoadLibrary(L"DllTest");
30 
31     if (hDll == NULL) std::cout << "failed to call LoadLibrary
";
32 
33     DWORD lastError = 0;
34 
35     if ((_Add = (pAdd)GetProcAddress(hDll, "Add")) == NULL)
36     {
37         std::cout << "failed to call GetProcAddress Add
" << std::endl;
38         lastError = GetLastError();
39         std::cout << "Add lastError = " << lastError << std::endl;
40     }
41 
42 
43     if ((_Sub = (pSub)GetProcAddress(hDll, "Sub")) == NULL)
44     {
45         std::cout << "failed to call GetProcAddress Sub
" << std::endl;
46         lastError = GetLastError();
47         std::cout << "Sub lastError = " << lastError << std::endl;
48     }
49 
50     int a = 10, b = 6, c = 17;
51     int addVal = _Add(a, b);
52 
53     int subVal = _Sub(a, b);
54 
55     std::cout << "addVal = " << addVal << ", subVal = " << subVal << std::endl;
56     FreeLibrary(hDll);
57 }
58 
59 void ImplicitCall()
60 {
61 
62     int a = 10, b = 6, c = 17;
63     int sum = Add(a, b);
64     int sub = Sub(a, b);
65     std::cout << "addVal = " << sum << ", subVal = " << sub << std::endl;
66 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值