用 aardio 我们可以简单地调用 C++ 代码
cac55 2024-09-20 12:58 42 浏览 0 评论
我们今天就不说下面这种 aardio 调用原生 API 如何简单:
var point = { INT x; INT y; }
::User32.GetCursorPos(point);
我们今天要玩一点难度高一些的,例如玩 C++ 地看到头都打转的 COM 接口,我们今天说的 COM 接口,也不说那种写起来累人用起来很舒服的 COM 控件。
我们今天要说几个难度高一些的:
1、直接调用 VC++ 实现了 IDispatch 接口指针。
2、直接用 C++ 专有的 thiscall 约定调用 C++ 对象。
一般调用 COM 控件,我们知道要先注册 COM 控件,但是一般注册 COM 控件还是比较麻烦,大多数需要管理权限注册,出现恼人的警告对话框,体验不是很好。在 aardio 中一般可以免管理权限注册,甚至可以免注册调用很多 COM 控件。
但是仍然有一些 COM 控件比较顽固是不能免注册调用的,其实 COM 控件注册啊什么的搞得很复杂,最终只是为了创建一个 IDispatch 对象,如果我们可以跳过上面这些所有的步骤,这会是非常舒服的。
我们用 VC++ 创建 IDispatch 对象,然后直接拿到原生的 IDispatch 接口指针,并且直接转换为 aardio 对象,这带来的好处是:
1、不用再注册 COM 控件了。
2、当然也不用什么免注册了。
3、可以直接通过内存加载 DLL,不用再带一个 DLL 文件了。
今天我们用 VC6 来写一个简单的 DLL 做一下演示,别小看 VC6,VC6 是唯一所有操作系统都自带的系统 C++ 运行时,所以可以生成极小的 DLL,而且一般是够用的,当然你要换新版 VC++ ,写法一样。
先看 aardio 调用代码有多简洁:
import console;
//加载 DLL
var dll = raw.loadDll(#34;/test.disp.dll",,"cdecl");
//创建 COM 对象,aardio 可自动支持 IDispatch 接口
import com;
var comObject = com.QueryObjectR( dll.CreateIDispatchObjectP() );
//使用 COM 对象
comObject.name = "测试";
console.log( comObject.name );
console.pause();
是不是简洁到难以置信?!
要做到上面的效果,一个编程语言需要同时做到能支持原生 API 开发,还要能支持 COM 动态接口对象,能做到这 2 样的编程语言其实非常少。而真正做到简洁方便好用的就更少了。
下面我们再看一下上面这个 test.disp.dll 的 C++ 源代码,这个先要有心理准备,世界上最复杂的编程语言不是白叫的,如果学 aardio 这样简单的编程语言让我叫苦不迭,我很难保证你看到下面的 C++ 代码不会晕过去。
不过我已经尽力把下面的代码处理到尽可能简单了,你不需要安装巨无霸的 VC++ 开发环境,直接运行下面的代码就可以编译生成 DLL,aardio 自带 VC6 扩展库。
import vc6;
import console;
var vc = vc6( "/",, console.open() )
//输入 C++ 源码
vc.cpp = /******
#include <afxwin.h>
#include <afxdisp.h>
class CTestObject: public CCmdTarget
{
DECLARE_DYNCREATE(CTestObject)
CTestObject();
protected:
virtual ~CTestObject();
CString strName;
public:
afx_msg BSTR GetName();
afx_msg void SetName(LPCTSTR lpszName);
DECLARE_DISPATCH_MAP()
};
IMPLEMENT_DYNCREATE(CTestObject, CCmdTarget)
CTestObject::CTestObject() {
EnableAutomation();
AfxOleLockApp();
}
CTestObject::~CTestObject() {
AfxOleUnlockApp();
}
BEGIN_DISPATCH_MAP(CTestObject, CCmdTarget)
DISP_PROPERTY_EX(CTestObject, "version", GetName, SetName, VT_BSTR)
END_DISPATCH_MAP()
BSTR CTestObject::GetName()
{
return strName.AllocSysString();
}
void CTestObject::SetName(LPCTSTR lpszName)
{
strName = lpszName;
}
extern "C" __declspec(dllexport) LPDISPATCH __cdecl CreateIDispatchObject() {
LPDISPATCH pDispatch = ( new CTestObject() )->GetIDispatch(FALSE);//参数FALSE指定不要添加引用计数
return pDispatch;
}
******/
//编译生成DLL
vc.exec(
'cl *.cpp'
,'/W3' /*警告等级*/
,'/MD' /*使用多线程动态运行库*/
,'/O2 /Ot /EHsc' /*代码优化选项*/
,'/D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "_AFXDLL" ' /*定义常数和宏*/
,'/I"./INCLUDE"'/*指定头文件目录*/
,'kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib' /*导入库*/
,'/link /SUBSYSTEM:WINDOWS /MACHINE:X86' /*后面是链接参数 */
,'/out:test.disp.dll'/*输出文件名*/
,'/dll' /*输出DLL*/
,'/LIBPATH:".\LIB" /LIBPATH:".\LIB2"' /*指定库目录*/
)
好吧,我们进入下一个目标,使用 thiscall 协议调用 C++ 对象,现在你见过 C++ 代码了,我就不再把 C++ 代码,aardio 代码分开发了,用 C++ 编译 DLL,再用 aardio 调用 C++ 对象,一锅炖:
import vc6;
import console;
console.open();
var vc = vc6( "/" )
//输入C++源码
vc.cpp = /******
#include <windows.h>
struct TestInfo{
int x;
int y;
BYTE name[256];
};
class CTestObject
{
public:
//注意函数声明前加上 virtual 以支持 aardio 中的 raw.interface
virtual void getName(char *buffer,int len);
virtual void getInfo(TestInfo *pInfo);
};
void CTestObject::getName(char *buffer,int len){
strcpy(buffer,"测试");
}
void CTestObject::getInfo(TestInfo *pInfo){
pInfo->x = 1;
pInfo->y = 2;
strcpy((char *)pInfo->name,"测试");
}
extern "C" __declspec(dllexport) CTestObject* __cdecl CreateTestObject() {
return new CTestObject();
}
extern "C" __declspec(dllexport) void __cdecl DeleteTestObject( CTestObject* pTest) {
delete pTest;
}
******/
//编译生成DLL
vc.exec(
'cl *.cpp'
,'/W3' /*警告等级*/
,'/MD' /*使用多线程动态运行库*/
,'/O2 /Ot /EHsc' /*代码优化选项*/
,'/D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL"' /*定义常数和宏*/
,'/I"./INCLUDE"'/*指定头文件目录*/
,'kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib' /*导入库*/
,'/link /SUBSYSTEM:WINDOWS /MACHINE:X86' /*后面是链接参数 */
,'/out:test.dll'/*输出文件名*/
,'/dll' /*输出DLL*/
,'/LIBPATH:".\LIB" /LIBPATH:".\LIB2"' /*指定库目录*/
)
var dll = raw.loadDll("/test.dll",,"cdecl");
import raw.interface;
class testObject{
ctor(){
//创建 C++ 对象,并获取指针,注意这里使用了 P 尾标获取指针。
var pTest = dll.CreateTestObjectP();
//C++ 对象指针转换为 aardio 对象。
this = ..raw.interface( pTest,"
void getName(string &buffer,int len);
void getInfo(struct &pInfo);
","thiscall" //注意调用约定为thiscall
)
//添加析构函数
..table.gc(this,"delete")
};
delete= function(){
if(!owner.deleted){
dll.DeleteTestObject( owner );
owner.deleted = true;
}
};
}
//创建对象
var obj = testObject();
//调用 C++ 函数
var name = obj.getName(25,25);
console.log(name);
//调用 C++ 函数
var info = obj.getInfo({ int x;int y;BYTE name[256]})
console.log( info.name );
console.pause();
好吧,如果你只是想试着跑几句 C++ 代码,并不想生成 DLL,就像硬盘干干净净的,还能跑一下 VC++ 代码,aardio 提供了一个 vc6.loadcode() 函数可以直接运行 VC++ 代码,示例如下:
import vc6;
import console;
console.showLoading(" 正在加载 C++ 代码");
var dll = vc6.loadcode(`
#include <windows.h>
#include <winioctl.h>
extern "C" {
__declspec( dllexport ) int __cdecl getValue() {
return CTL_CODE(IOCTL_STORAGE_BASE, 0x0500, METHOD_BUFFERED, FILE_ANY_ACCESS);
}
}`);
var value = dll.getValue();
var str = string.format("0x%X",value);
console.log("已复制: " + str,value);
import win.clip;
win.clip.write(str);
console.pause();
相关推荐
- 无力吐槽的自动续费(你被自动续费困扰过吗?)
-
今天因为工作需要,需要在百度文库上下载一篇文章。没办法,确实需要也有必要,只能老老实实的按要求买了个VIP。过去在百度文库上有过类似经历,当时为了写论文买了一个月的VIP,后面也没有太注意,直到第二个...
- 百度文库推出“文源计划”创作者可一键认领文档
-
11月7日,百度文库发布了旨在保护创作者权益的“文源计划”。所谓“文源计划”,即为每一篇文档找到源头,让创作者享受更多的权益。据百度文库总经理李小婉介绍,文源计划分为三部分,分别是版权认证、版权扶持和...
- 有开放大学学号的同学,百度文库高校版可以用了。
-
还在网上找百度文库的下载方式,只要从身边的朋友在读开放大学的,那他(她)的学号就可以登陆到国家开放大学图书馆,还使用百度文库高校版来下载。与百度文库稍有不同,但足够使用了。现转国图链接如下:htt...
- 搜索资源方法推荐(搜索资源的方法)
-
今天msgbox就要教大家如何又快又准的搜到各类资源,第一点,排除干扰百度搜索出来啊经常前排展示它的产品以及百度文库,如何去除呢?很简单,后面输入空格减号百度文库,比如你搜高等数学百度文库很多,只要后...
- 一行代码搞定百度文库VIP功能(2021百度文库vip账号密码共享)
-
百度文库作为大家常用查资料找文档的平台,大多数文档我们都可以直接在百度文库找到,然而百度文库也有让人头痛的时候。好不容易找到一篇合适的文档,当你准备复制的时候他却提示你需要开通VIP才能复制~~~下载...
- 百度文库文档批量上传工具用户说明书
-
百度文库文档批量上传工具用户说明书1、软件主要功能1、批量上传文档到百度文库,支持上传到收费、VIP专享、优享以及共享。2、支持自动分类和自动获取标签3、支持多用户切换,一个账户传满可以切换到...
- 百度文库现在都看不到文档是否上传成功,要凉了吗?
-
打开知识店铺,百度文库文档里显示都是下载这一按键,上传的文档也看不到是否成功?咋情况,要取消了吗?没通过审核的也不让你删除,是几个意思,想通吃吗?现在百度上传文档也很费劲,有时弄了半天的资料上传审核过...
- 微信推广引流108式:利用百度文库长期分享软文引流
-
百度文库相对于百度知道、百度百科来说,操作上没那么多条条框框,规则上也相对好把握些。做一条百度知道所花费的精力一般都会比做一条百度文库的要多些,老马个人操作下来觉得百度文库更好把握。但见仁见智吧,今天...
- 职场“避雷”指南 百度文库推出标准化劳动合同范本
-
轰轰烈烈的毕业季结束了,众多应届生在经过了“职场海选”后,已正式成为职场生力军的一员。这一阶段,除了熟悉业务,签订劳动合同、了解职场福利也迅速被提上日程。而随着国人法律意识的增强,百度文库内《劳动合同...
- 《百度文库》:素材精选宝库(百度文库官网首页)
-
《百度文库》:独特功能助力选择高质量素材在当今信息爆炸的时代,如何高效地获取并利用有价值的素材成为了许多人面临的挑战。而《百度文库》作为百度公司推出的一款在线文档分享平台,凭借其丰富的资源、强大的功能...
- 深度整合和开放AI能力 百度文库和网盘推出内容操作系统「沧舟OS」
-
【TechWeb】4月25日消息,Create2025百度AI开发者大会上,百度文库和百度网盘推出全球首个内容操作系统——沧舟OS。基于沧舟OS,百度文库APP全新上线「GenFlow超能搭子」...
- 女子发现大二作业被百度文库要求付费下载,律师:平台侵权,应赔偿
-
近日,28岁的黎女士在百度百科搜索家乡的小地名时,发现了自己在大二完成的课题作业。她继续搜索,发现多个平台收录了该文,比如豆丁网和文档之家等,有的还设置了付费或积分下载。2月15日,九派新闻记者以用户...
- 2016杀入百度文库的新捷径,只有少数人才知道的喔
-
百度的产品在SEO优化中的分量真不用多说,其实很多人都像我一样一直在找捷径。但是我经常发现很多人都是在用死方法。比如发贴吧发帖而不知道去申请一个吧主,知道自问自答而不知道去申请一个合作资格。口碑和贴吧...
- 百度文库付费文档搜索方法(百度文库付费文档搜索方法有哪些)
-
一直以来,百度文库中无论是个人中心还是个人主页,都没有像淘宝一样的店内搜索功能,连最近新开的知识店铺也没有设计店内搜索功能,这无论是对上传用户还是下载用户都不方便,上传用户想要搜索自己的文档无法办到...
- 供读者免费使用!泰达图书馆机构版百度文库新年上新啦
-
在泰达图书馆读者使用百度文库数字资源不需要VIP,免-费-用!惊不惊喜?快来了解一下吧……新年伊始,为满足区域企业、高校、科研院所以及居民群众在教学、科研及学习过程中,对各类文献资源的需求,泰达图书馆...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- 如何绘制折线图 (52)
- javaabstract (48)
- 新浪微博头像 (53)
- grub4dos (66)
- s扫描器 (51)
- httpfile dll (48)
- ps实例教程 (55)
- taskmgr (51)
- s spline (61)
- vnc远程控制 (47)
- 数据丢失 (47)
- wbem (57)
- flac文件 (72)
- 网页制作基础教程 (53)
- 镜像文件刻录 (61)
- ug5 0软件免费下载 (78)
- debian下载 (53)
- ubuntu10 04 (60)
- web qq登录 (59)
- 笔记本变成无线路由 (52)
- flash player 11 4 (50)
- 右键菜单清理 (78)
- cuteftp 注册码 (57)
- ospf协议 (53)
- ms17 010 下载 (60)