目录
动态链接库声明方式
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++_学习笔记