创建动态链接库(dll)

目录

动态链接库声明方式

解决函数名字改编的问题:模块定义文件(.DEF)

新建DLL步骤

_declspec(dllexport)方法

代码

MyDll0.h

MyDll0.cpp

MyDll0导出效果

模块定义.def方法

添加.def途径一【推荐此种】

添加.def途径二

代码

MyDll.h

MyDll.cpp

MyDll.def

MyDll导出效果


动态链接库声明方式

extern "C" _declspec(dllexport) int _stdcall add(int a, int b);

extern "C":一种编译器限定符,限定使用C语言编译器,导出的函数名称不发生改编。

可以解决C++与C语言之间相互调用时函数命名的问题。

缺点:不能导出类的成员函数,只能导出全局函数。

【注意】C要大写并加双引号

如果不加extern "C",表明使用C++编译器方式,导出的函数名称会被改编。

因为C++支持重载,为了区分重名的函数,C++编译器会按照自己的规则来篡改函数名称。

所以,不同的C++编译器生成的程序在调用对方提供的函数时,可能会出现问题。

_declspec(dllexport):导出函数标识符。_declspec(dllimport):导入函数标识符

_stdcall:调用约定标识符。_stdcall是标准调用约定,即WINAPI调用约定,也即PASCAL调用约定,函数名字会发生改编

Delphi语言也是标准调用约定。

没有加_stdcall,表明是C调用约定,导出的函数名称不会被改编,

指的是这种情况“extern "C" _declspec(dllexport) int add(int a, int b);  // C 编译方式,函数名字不变”。

组合方式有如下几种

_declspec(dllexport) int add(int a, int b);     // C++ 编译方式,函数名字被改编
extern "C" _declspec(dllexport) int add(int a, int b);  // C 编译方式,函数名字不变
_declspec(dllexport) int _stdcall add(int a, int b);     // 调用约定为_stdcall,函数名字被改编

// 调用约定为_stdcall,函数名字被改编,extern "C"不起作用
extern "C" _declspec(dllexport) int _stdcall add(int a, int b);

解决函数名字改编的问题:模块定义文件(.DEF)

LIBRARY MYDLL3

EXPORTS
   add
   subtract

定义规则

entryname[=internal_name|other_module.exported_name] [@ordinal [NONAME] ] [ [PRIVATE] | [DATA] ]

参考文档:微软官方说明

EXPORTS
   DllCanUnloadNow      @1          PRIVATE
   DllWindowName = WindowName       DATA
   DllGetClassObject    @4 NONAME   PRIVATE
   DllRegisterServer    @7
   DllUnregisterServer

新建DLL步骤

_declspec(dllexport)方法

代码

MyDll0.h

#pragma once
#ifndef _MYDLL_API 
#define _MYDLL_API extern "C" _declspec(dllexport)
#else
#define _MYDLL_API extern "C" _declspec(dllimport)
#endif

_MYDLL_API int _stdcall add(int a, int b);
_MYDLL_API int _stdcall subtract(int a, int b);

MyDll0.cpp

#include "MyDll0.h"

_MYDLL_API int _stdcall add(int a, int b)
{
    return a + b;
}

_MYDLL_API int _stdcall subtract(int a, int b)
{
    return a - b;
}

MyDll0导出效果

【说明】上面的代码最终使用_stdcall调用约定,所以名字会发生改编,如下图:

// 调用约定为_stdcall,函数名字被改编,extern "C"不起作用
extern "C" _declspec(dllexport) int _stdcall add(int a, int b);

模块定义.def方法

添加.def途径一【推荐此种】

添加.def途径二

新建一个MyDll.def,然后按照下面图示添加。

代码

【注意】函数声明中没有extern "C",也没有 _declspec(dllexport)

MyDll.h

int add3(int a, int b);
int subtract3(int a, int b);

MyDll.cpp

#include "MyDll.h"
int add3(int a, int b)
{
    return a + b;
}

int subtract3(int a, int b)
{
    return a - b;
}

MyDll.def

【注意】不同之处在此

关于EXPORTS的用法可以参考微软官方文档EXPORTS

LIBRARY MYDLL

EXPORTS
	add=add3
	subtract=subtract3

MyDll导出效果

名字没有被改编

更多内容请看C/C++动态链接库(DLL)详解

来源:孙鑫_VC++_学习笔记

发布了85 篇原创文章 · 获赞 82 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/yl_best/article/details/100924457
今日推荐