用__stdcall实现易语言调用C/C++的dll
0x0 前言
大家好啊!我是逆向区的版主,今天我到编程区的来水帖子了!
有些朋友问我,易语言的功能好少啊,我好多想法都没法实现,我想能不能用易语言调用c的dll呢?
答:可以!!!
0x1准备工作--工程
首先我们需要一个VS,VS下载和安装想必大家都知道的。
我们打开之后新建个项目,或者(Ctrl+shift+n)
出来个这个界面
我们是写的C++,所以左边点C++,然后是dll,选择MFC dll
名字大家随便填啊,完成之后确定
稍等片刻会出现这个界面。
此时我们需要注意下
不要点完成,而是点下一步!!
这边选择带静态的规则
为什么不选默认的第一个呢?这是因为由于操作系统不同,系统关键函数dll也不相同,
为了防止在其他系统虽然有dll文件但找不到函数的问题
这里使用第二个静态规则,然后点完成。
0x3 准备工作--->cpp文件
如图
点击左下角的解决方案管理器,展开所有文件,找到源文件中的cpp,打开。
代码如下
// dllll.cpp : 定义 DLL 的初始化例程。
//
#include "stdafx.h"
#include "dllll.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
//
//TODO: 如果此 DLL 相对于 MFC DLL 是动态链接的,
//则从此 DLL 导出的任何调入
//MFC 的函数必须将 AFX_MANAGE_STATE 宏添加到
//该函数的最前面。
//
//例如:
//
//extern "C" BOOL PASCAL EXPORT ExportedFunction()
//{
// AFX_MANAGE_STATE(AfxGetStaticModuleState());
// // 此处为普通函数体
//}
//
//此宏先于任何 MFC 调用
//出现在每个函数中十分重要。这意味着
//它必须作为函数中的第一个语句
//出现,甚至先于所有对象变量声明,
//这是因为它们的构造函数可能生成 MFC
//DLL 调用。
//
//有关其他详细信息,
//请参阅 MFC 技术说明 33 和 58。
//
// CdllllApp
BEGIN_MESSAGE_MAP(CdllllApp, CWinApp)
END_MESSAGE_MAP()
// CdllllApp 构造
CdllllApp::CdllllApp()
{
// TODO: 在此处添加构造代码,
// 将所有重要的初始化放置在 InitInstance 中
}
// 唯一的一个 CdllllApp 对象
CdllllApp theApp;
// CdllllApp 初始化
BOOL CdllllApp::InitInstance()
{
CWinApp::InitInstance();
return TRUE;
}
[color=rgb(51, 102, 153) !important]复制代码
我们整理下,是这样的:
#include "stdafx.h"
#include "dllll.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
BEGIN_MESSAGE_MAP(CdllllApp, CWinApp)
END_MESSAGE_MAP()
CdllllApp::CdllllApp(){}
CdllllApp theApp;
BOOL CdllllApp::InitInstance(){CWinApp::InitInstance();return TRUE;}
[color=rgb(51, 102, 153) !important]复制代码
大家注意下代码里面的CxxxxxxxxxxxxApp;xxxxxxxxxxxxxx会随着你的工程文件名更改而更改,一般创建好了都有自带代码的,不用删,把注释整理(或删除)就行。!
0x4 开干--->写几个测试函数
我们用加法和减法函数,大家也可以用其他函数试试!(可能要加头文件)
我们在刚才的整理后的代码加上这些代码:
int __stdcall newadd(int a,int b){
return (a+b);}
int __stdcall newsub(int a,int b){
return (a-b);}
[color=rgb(51, 102, 153) !important]复制代码
此时就写完了主要代码了
接下来函数写完了
我们来写def定义文件(左边的解决方案管理器里面双击)
原来的默认代码是这样的:
; dllll.def : 声明 DLL 的模块参数。
LIBRARY
EXPORTS
; 此处可以是显式导出
[color=rgb(51, 102, 153) !important]复制代码
我们改成我们的:
; dllll.def : 声明 DLL 的模块参数。
LIBRARY "dllll"
EXPORTS
newadd
newsub
[color=rgb(51, 102, 153) !important]复制代码
其中LIBRARY "xxxxxxxxxxxx"中的xxxxxx写这个工程的名字,(就是def文件的名字,这里是dllll)EXPORTS下面一行就是你要保留函数名的函数,这里看cpp的代码就是newadd和newsub
可以依次叠加。
完事之后编译就行
重新生成(Ctrl+Alt+F7)
等待生成完毕我们去工程文件的目录(一开始创建的窗口注意下位置):
把这个dll复制出来。
0x4 调用
打开易语言,我们画两个编辑框,两个按钮
代码如下,dll声明:
.版本 2
.DLL命令 DLL命令1, 短整数型, "dllll.dll", "newadd"
.参数 a, 短整数型
.参数 b, 短整数型
.DLL命令 DLL命令2, 短整数型, "dllll.dll", "newsub"
.参数 a, 短整数型
.参数 b, 短整数型
[color=rgb(51, 102, 153) !important]复制代码
其中的dll命令名大家随便写,这个是在易语言显示的名字
库文件名就写刚才那个dll的名字,因为放同一个目录,这里就不写目录路径了,大家需要的自己补
在库中对应名看刚才的def文件,对应好了,多一个或者少一个字符都无效的。
然后c的int型对应的是短整数型,这里大家看下。
然后是程序集:
.版本 2
.程序集 窗口程序集_启动窗口
.子程序 _按钮1_被单击
信息框 (到文本 (DLL命令1 (到数值 (编辑框1.内容), 到数值 (编辑框2.内容))), 0, , )
.子程序 _按钮2_被单击
信息框 (到文本 (DLL命令2 (到数值 (编辑框1.内容), 到数值 (编辑框2.内容))), 0, , )
[color=rgb(51, 102, 153) !important]复制代码
好了我们静态编译(Shift+F7)。
测试下:
完美!!
附件如下:
/i4yml7i