[dll] Use vs to compile dynamic link library dll and use under windows

1. Demand

 Compile the function library dll based on c language that can be used by other platforms.

2. Foreword

 There are many related operations on the Internet, but some of the instructions are not detailed or there is no supporting schematic diagram, which leads to difficulties in the operation, and when using vs, various configurations are required to cause the compilation to fail, so I am going to record every step of the operation to ensure According to the operation steps, the dll library can be successfully generated. It is divided into two parts. The first part is project creation. After testing various project types, the following methods can reduce more configuration operations. The second part is c code writing, which involves some keywords and declared operations of MicrosoftVC.

3. Code engineering and project operation

It is installed by default and can use visual stdio to develop projects normally.

3.1 New project

Tab card in the upper left corner, "File" -> "New" -> "Project", as shown below:

3.2 Use the wizard to create a new one

After testing multiple project classes, other classes need to be created and configured. After using the wizard to create a new project, you can directly compile and generate a dll library. Therefore, select "Visual C++" -> "Windows Desktop" -> "Windows Desktop Wizard", name the project and confirm the generation, as shown below:

 3.3 Select application type

The application type is ".exe" by default, and you need to enter the drop-down box to select "Dynamic Link Library (dll)". Then check "Empty Project" to ensure that the code in the newly generated project is clean. As shown below: 

3.4 Created

At this point, the project-related operations have been completed.

3.5 Platform switching

The default is the x86 platform, and it needs to be switched to the x64 platform, otherwise the generated dll will cause incompatibility and cannot be read accurately. The configuration is as shown in the figure:

Four, c code operation

The file creation and basic declaration are omitted, and the source code will be placed in the appendix at the end of the article.

4.1 Statement modification

If you want to use dll, you need to use "__declspec(dllexport)" and "__declspec(dllimport)" keywords to modify the external declaration of the function.

  • __declspec(dllexport): A function used to generate dll for data export by compiling
  • __declspec(dllimport): Function used to obtain imported data by calling dll

The above modification is generally before the function type declaration, as follows:

 4.2 compile

After the compilation is successful, a dll file corresponding to the project name will be generated in the subdirectory, as follows:

Five, verify the use

Verification requires another brand new project, such as a console application with "hello world!".

5.1 Header file declaration

The mandatory declarations are as follows:

#include<Windows.h>//必备

 5.2 Read dll file

Use the LoadLibrary function to read and receive with HINSTANCE type variables.

HINSTANCE hDll = LoadLibrary(_T("dll1.dll"));
if (hDll == NULL) {
	printf("lib not exist.");
	return 1;
}

 5.3 Defining function types

The declaration type and parameter type of the dll function are known.

using functionPtrCreate = t_obj*(*)();
using functionPtrSetID = void(*)(t_obj*,long);
using functionPtrGetID = long(*)(t_obj*);

5.4 GetProcAddress load function

functionPtrCreate objCreate = (functionPtrCreate)GetProcAddress(hDll, "objCreate");
functionPtrSetID objSetID = (functionPtrSetID)GetProcAddress(hDll, "objSetID");
functionPtrGetID objGetID = (functionPtrGetID)GetProcAddress(hDll, "objGetID");

5.5 Use the loaded function to output the result

enter:

objSetID(temp, 10086);

 output:

std::cout << objGetID(temp);

result: 

Appendix source code

1、dll_config_global.h

#ifndef _DLL_CONFIG_GLOBAL_H_
#define _DLL_CONFIG_GLOBAL_H_

/*逻辑分支,判断环境*/
#if defined(_MSC_VER) || defined(WIN64) || defined(_WIN64) || defined(__WIN64__) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
#  define DLL_CONFIG_DECL_EXPORT __declspec(dllexport)//用于dll数据导出
#  define DLL_CONFIG_DECL_IMPORT __declspec(dllimport)//用于导入dll数据
#else
#  define DLL_CONFIG_DECL_EXPORT     __attribute__((visibility("default")))//失效
#  define DLL_CONFIG_DECL_IMPORT     __attribute__((visibility("default")))//失效
#endif

#endif // _DLL_CONFIG_GLOBAL_H_

 2、dll_demo.h

#ifndef _DLL_DEMO_H_
#define _DLL_DEMO_H_

/*dll编译需要使用的全局配置文件*/
#include "dll_config_global.h"

/*c库*/
#include<stdio.h>
#include<stdint.h>
#include<stdlib.h>
#include<stdbool.h>
#include<string.h>
#include<math.h>

/*结构体类声明*/
typedef struct _obj {
	bool En;//使能
	long ID;//id
	const char * name;//一般名称
	void * data;//数据包
} t_obj;//基本对象

/*函数外部声明*/
#ifdef _cplusplus
extern "C" {
#endif // _cplusplus{}

	DLL_CONFIG_DECL_EXPORT t_obj* objCreate();
	DLL_CONFIG_DECL_EXPORT void objEnable(t_obj*obj);
	DLL_CONFIG_DECL_EXPORT void objDisable(t_obj*obj);
	DLL_CONFIG_DECL_EXPORT bool objGetEn(t_obj*obj);
	DLL_CONFIG_DECL_EXPORT void objClearID(t_obj*obj);
	DLL_CONFIG_DECL_EXPORT void objSetID(t_obj*obj, long val);
	DLL_CONFIG_DECL_EXPORT long objGetID(t_obj*obj);
	DLL_CONFIG_DECL_EXPORT void objClearName(t_obj*obj);
	DLL_CONFIG_DECL_EXPORT void objSetName(t_obj*obj, char*val);
	DLL_CONFIG_DECL_EXPORT const char* objGetName(t_obj*obj);
	DLL_CONFIG_DECL_EXPORT void objClearData(t_obj*obj);
	DLL_CONFIG_DECL_EXPORT void objSetData(t_obj*obj, void*p, long length);
	DLL_CONFIG_DECL_EXPORT void* objGetData(t_obj*obj);

#ifdef _cplusplus

#endif // _cplusplus{}


#endif // _DLL_DEMO_H_

3、dll_demo.c

#include"dll_demo.h"

//----节0
/*创建基本对象*/
DLL_CONFIG_DECL_EXPORT t_obj* objCreate() {
	return (t_obj*)malloc(sizeof(t_obj));
}

//----节1
/*使能对象*/
DLL_CONFIG_DECL_EXPORT void objEnable(t_obj*obj)
{
	obj->En = true;
}
/*失能对象*/
DLL_CONFIG_DECL_EXPORT void objDisable(t_obj*obj)
{
	obj->En = false;
}
/*获取对象状态*/
DLL_CONFIG_DECL_EXPORT bool objGetEn(t_obj*obj)
{
	return obj->En;
}

//----节2
/*清空id*/
DLL_CONFIG_DECL_EXPORT void objClearID(t_obj*obj)
{
	obj->ID = 0x00;
}
/*设置id*/
DLL_CONFIG_DECL_EXPORT void objSetID(t_obj*obj,long val)
{
	obj->ID = val;
}
/*获取对象id*/
DLL_CONFIG_DECL_EXPORT long objGetID(t_obj*obj)
{
	return obj->ID;
}

//----节3
/*清空名称*/
DLL_CONFIG_DECL_EXPORT void objClearName(t_obj*obj)
{
	obj->name = NULL;
}
/*设置名称*/
DLL_CONFIG_DECL_EXPORT void objSetName(t_obj*obj,char*val)
{
	obj->name = val;
}
/*获取对象名称*/
DLL_CONFIG_DECL_EXPORT const char* objGetName(t_obj*obj)
{
	return obj->name;
}

//----节4
/*清空数据包*/
DLL_CONFIG_DECL_EXPORT void objClearData(t_obj*obj)
{
	free(obj->data);
	obj->data = NULL;
}
/*设置数据包*/
DLL_CONFIG_DECL_EXPORT void objSetData(t_obj*obj,void*p,long length)
{
	obj->data = malloc(length);
	memcpy(obj->data, p, length);
}
/*获取对象数据包*/
DLL_CONFIG_DECL_EXPORT void* objGetData(t_obj*obj)
{
	return obj->data;
}


4、dllUse.cpp

#include<iostream>
#include<Windows.h>//必备
#include<tchar.h>
//#pragma comment(lib,"dll1.lib")
typedef struct _obj {
	bool En;//使能
	long ID;//id
	const char * name;//一般名称
	void * data;//数据包
} t_obj;//基本对象

int main()
{
	HINSTANCE hDll = LoadLibrary(_T("dll1.dll"));
	if (hDll == NULL) {
		printf("lib not exist.");
		return 1;
	}
	using functionPtrCreate = t_obj*(*)();
	using functionPtrSetID = void(*)(t_obj*,long);
	using functionPtrGetID = long(*)(t_obj*);
	//找到所需要的函数
	
	functionPtrCreate objCreate = (functionPtrCreate)GetProcAddress(hDll, "objCreate");
	functionPtrSetID objSetID = (functionPtrSetID)GetProcAddress(hDll, "objSetID");
	functionPtrGetID objGetID = (functionPtrGetID)GetProcAddress(hDll, "objGetID");
	t_obj* temp = objCreate();
	objSetID(temp, 10086);
	std::cout << objGetID(temp);

}

Guess you like

Origin blog.csdn.net/qq_34217861/article/details/126537073
Recommended