在很早之前就试过写个 dll,当时被各种符号弄晕了,现在再尝试在 VS2015 上写 dll,发现超级方便啊。不过在生成的时候发现 Release 与 Debug 的 dll 重名,直接修改名字会导致错误,最终解决了这个问题,与大家分享下。
写一个 dll 文件
有了 VS2015,这一步已经非常简单了:新建一个 Win32 控制台应用程序,然后在创建的时候勾选导出符号与预编译头,然后点击完成。
完毕后,会自动生成一个. h 文件与一个. cpp 文件:
.h 文件如下:
// 下列 ifdef 块是创建使从 DLL 导出更简单的
// 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 MY_DLL_EXPORTS
// 符号编译的。在使用此 DLL 的
// 任何其他项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将
// MY_DLL_API 函数视为是从 DLL 导入的,而此 DLL 则将用此宏定义的
// 符号视为是被导出的。
#ifdef MY_DLL_EXPORTS
#define MY_DLL_API __declspec(dllexport)
#else
#define MY_DLL_API __declspec(dllimport)
#endif
// 此类是从 my_dll.dll 导出的
class MY_DLL_API Cmy_dll {
public:
Cmy_dll(void);
// TODO: 在此添加您的方法。
};
extern MY_DLL_API int nmy_dll;
MY_DLL_API int fnmy_dll(void);
.cpp 文件如下:
// my_dll.cpp : 定义 DLL 应用程序的导出函数。
//
#include "stdafx.h"
#include "my_dll.h"
// 这是导出变量的一个示例
MY_DLL_API int nmy_dll=0;
// 这是导出函数的一个示例。
MY_DLL_API int fnmy_dll(void)
{
return 42;
}
// 这是已导出类的构造函数。
// 有关类定义的信息,请参阅 my_dll.h
Cmy_dll::Cmy_dll()
{
return;
}
太贴心了有木有,不需要写任何一句奇怪的话,想写什么直接替换就可以了。
我们修改下上面的文件,添加几个简单的函数,用于测试:
//.h
// 此类是从 my_dll.dll 导出的
class MY_DLL_API Cmy_dll {
public:
Cmy_dll(void);
// TODO: 在此添加您的方法。
int a;
int b;
int fun();
};
extern MY_DLL_API int nmy_dll;
MY_DLL_API int fnmy_dll(int a, int b);
//.cpp
MY_DLL_API int nmy_dll=123;
// 这是导出函数的一个示例。
MY_DLL_API int fnmy_dll(int a, int b)
{
return a+b;
}
// 这是已导出类的构造函数。
// 有关类定义的信息,请参阅 my_dll.h
Cmy_dll::Cmy_dll()
{
return;
}
int Cmy_dll::fun()
{
return a*b;
}
然后直接生成 DLL 就可以了。
调用 dll
将生成的 .lib .dll 与之前的 .h 文件加入到新的项目目录下,然后采用如下方式调用:
#include "stdafx.h"
#include <iostream>
#include "my_dll.h"
using namespace std;
#pragma comment(lib,"my_dll")
int main()
{
int a, b;
cin >> a >> b;
cout << fnmy_dll(a, b) << endl;
Cmy_dll test;
test.a = a;
test.b = b;
cout << test.fun() << endl;
cout << nmy_dll << endl;
system("pause");
return 0;
}
结果:
解决Release编译与Debug编译生成的dll重名的问题
我在写 dll 的时候遇到了一个问题,由于我使用了opencv 而 opencv debug 与 release 下面是不能通用的 因此我在 release下生成的dll 在dubug编译时调用会报错,但是生成的两个dll名字相同,如果直接改名,会导致 lib文件识别不了 dll。
按照如下图所示修改项目属性,就可以修改生成dll的名字 。
就像opencv一样,我们让debug编译生成的dll名字后面带个’d’。生成以后,会发现dll名字变了,但是lib名字没有改变,只需要直接重命名修改即可。这样,我们就可以直接将两个dll同时放到项目下而不会冲突了。