标签:win 点击 默认值 data 打开 height 程序 src 确定调用
操作系统: Win7
开发软件: VS2010
建立win32控制台工程MyLib(或者win32项目中下的静态库), 添加mySub.h文件以及mySub.cpp文件。
编写mySub.h文件代码
#ifndef _MYSUB_H // 这里的#ifndef可以避免头文件重复包含
#define _MYSUB_H
void mySub(int a,int b); // 这一行代码不能够写在上一行,只能另起一行写
#endif
编写mySub.cpp文件代码
#include "mySub.h" //包含头文件
#include <iostream>
void mySub(int a,int b) //自定义的函数
{
std::cout<<(a-b)<<std::endl;
}
由于在工程中,没有main()函数,所以编译可能会出错。这时,点击工程,并选择工程属性,出现下图,选择静态链接库即可。
新建一个.cpp文件myLibTest.cpp(用于测试)
#include <iostream>
#include "mySub.h" // 引用头文件
using namespace std;
#pragma comment(lib,"MyLib.lib") // 导入上一步生成的lib文件
int main()
{
mySub(5,4); // 调用lib中的自定义函数mySub()
return 0;
}
点击工程,并选择工程属性,出现下图,将附加库目录新增包含刚才生成.lib的目录。
新建win32项目,项目名称为SubDLL,解决方案名称为DLLTest,下一步。
选择应用程序类型为DLL,将附加选项的“导出符号”勾选上,完成。
修改SubDLL.h中的内容(将原来代码中,除预处理部分的代码外全部删除),并在后面新增你要实现的函数声明(见代码第21行)。注意:项目名为SubDLL,但此时生成的名字为 SUBDLL。
#ifdef SUBDLL_EXPORTS
#define SUBDLL_API __declspec(dllexport)
#else
#define SUBDLL_API __declspec(dllimport)
#endif
/*
// 此类是从 SubDLL.dll 导出的
class SUBDLL_API CSubDLL {
public:
CSubDLL(void);
// TODO: 在此添加您的方法。
};
extern SUBDLL_API int nSubDLL;
SUBDLL_API int fnSubDLL(void);
*/
//这边是新增的内容
SUBDLL_API void mySub();
修改SubDLL.cpp中的内容(将原来代码中,除头文件引入部分的代码外全部删除),并在后面新增你要实现的函数声明(见代码第26行)。
// SubDLL.cpp : 定义 DLL 应用程序的导出函数。
//
#include "stdafx.h"
#include "SubDLL.h"
#include<stdio.h>
/*
// 这是导出变量的一个示例
SUBDLL_API int nSubDLL=0;
// 这是导出函数的一个示例。
SUBDLL_API int fnSubDLL(void)
{
return 42;
}
// 这是已导出类的构造函数。
// 有关类定义的信息,请参阅 SubDLL.h
CSubDLL::CSubDLL()
{
return;
}
*/
//这边为SUM()的内容,很简易
SUBDLL_API void mySub(int a,int b)
{
printf("the result is %d",a-b);
}
点击“项目”,选择“属性”,进行如下图的配置(粗体字显示部分)。
在之前“解决方案”中新建项目(选中解决方案 -> 增加 -> 新建项目),这次选择“win32控制台应用程序”,生成向导中选择“空项目”即可。取名为MyTest。
在新建项目的源文件下新建一个UseDLL.cpp文件,下面是其中的代码。
#include <iostream>
#include <Windows.h> //使用函数和某些特殊变量
using namespace std;
typedef void (*FUN)(int,int); //定义一个函数指针,确定调用函数的形参
int main()
{
const char* dllname = "SUBDLL.dll"; // 加载.dll
const char* funname = "mySub"; //SUMDLL.cpp中函数名称
HMODULE hDLL = LoadLibrary(dllname); //不要问,跟着做
if (hDLL != NULL)
{
FUN fp = FUN(GetProcAddress(hDLL,funname)); //继续做,不要问
if(fp != NULL)
{
fp(5,4);
}
else
{
cout << "Can not Find: " << funname << endl;
}
FreeLibrary(hDLL);
}
else
cout << "Can not find: " << dllname;
return 0;
}
点击解决方案名,选择设置启动项目 -> 通用属性 -> 启动项目 -> 单启动项目(选中UseDLL)。
运行项目,出现了错误:Can not find:mySub
。造成这种错误的原因正是导出函数的修饰名称。在dll二进制文件中,经过编译器的“加工”,实际上有了不同的名称。这也是函数重载机制得以实现的一个技术支持。怎么办呢?我们可以通过vs2010附带工具dumpbin,找到加工以后的名称。详见dumpbin工具的使用
为了能够使原来的UseDLL.cpp(上面第2步所示代码)成功运行,可以进行下列操作:
在生成DLL文件的SubDLL项目的源文件中新建模块定义文件createDLL.def,其中的代码如下:
LIBRARY createDLL
EXPORTS
mySub = ?mySub@@YAXHH@Z //?mySub@@YAXHH@Z 即为dumpbin工具找到的真实名。
修改SubDLL.h中的代码(去掉这些不太规范的修饰名称),修改之后重新编译生成CreateDLL.dll。
#ifdef SUBDLL_EXPORTS
#define SUBDLL_API //去掉了原来的 __declspec(dllexport)
#else //或改为 #define SUBDLL_API extern "C" __declspec(dllexport)
#define SUBDLL_API //同上
#endif
重新运行UseDLL.cpp程序,成功执行。
在之前“解决方案”中新建项目(选中解决方案 -> 增加 -> 新建项目),这次选择“win32控制台应用程序”,生成向导中选择“空项目”即可。取名为MyTest。
在新建项目的源文件下新建一个UseDLL.cpp文件,下面是其中的代码。
#include <iostream>
extern void mySub(int,int);
int main()
{
mySub(5,4);
return 0;
}
右键工程–>Linker–>General–>Additional Library Directories(附加库目录) –>找到那个SubDLL.lib所在的目录
右键UseDLL工程–>Linker->input写下lib的名称。如SubDLL.lib和你DEBUG文件下的对应(这步没有也可以,因为会在上一步的路径下寻找)。
点击解决方案名,选择设置启动项目 -> 通用属性 -> 启动项目 -> 单启动项目(选中UseDLL)
运行UseDLL.cpp程序,成功执行。
error C2664: “LoadLibraryW”: 不能将参数 1 从“const char [10]”转换为“LPCWSTR”与指向的类型无关;转换要求 reinterpret_cast、C 样式转换或函数样式转换
解决方法:
选中项目,然后点击属性——>配置属性——>常规——>项目默认值——>字符集,选为“使用多字节字符集"
fatal error LNK1104: 无法打开文件:×××.lib的解决办法
一般情况是因为没有导入相应的.lib文件,或者是导入的路径有误。给项目添加库文件路径。
在VS中右击项目点属性:
配置属性-->链接器-->常规-->附加目录 。在里面填上库文件所在的路径即可。
fatal error LNK1104: 无法打开文件“x x x.def”
如果不想使用xxx.def文件,可以在项目-属性-配置属性-链接器-输入 选项中,将右侧的模块定义文件删掉,这样就不会提示了。
添加头文件:
配置属性-->C/C++-->常规-->附加包含目录 加上头文件存放的目录。
添加lib文件:
在当前目录下运行命令:shift键 + 鼠标右键
首先将命令窗体属性中的快速编辑模式选中打勾,这样就可以一复制粘贴了。复制dos窗体中的内容:右键->标记->选择复制内容->回车键或者鼠标右击,粘贴的时候:鼠标右键粘贴。
dos中不能使用快捷键。
标签:win 点击 默认值 data 打开 height 程序 src 确定调用
原文地址:https://www.cnblogs.com/wjcoding/p/11232570.html