JS与C++交互方法汇总

大家都知道通过Idispatch接口可使C++与动态语言交互, 本文分别列出各种交互方法,并着重讲解我说喜欢的一种方法,希望给网友们一些帮助,同时欢迎大家推敲和讨论

1、连接点事件,此法请参考vckbase杨老师博客

2、事件和通知,参考vckbase杨老师博客

上述两法的弊端在于:客户必须实现一个接收器,对于不同的语言实现接收器的方式各不同,如js接收器必须用特定的html标签标识出来,且只能是嵌入在html文档里面,不适和单独的js脚本,此法使用如下:

<script   language= "javascript "   for= "window "   event= "onload ">

也可下载示例代码看看每种接收器的具体实现:atl连接点、c++接收器、js接收器


总之,使用连接点有太多不便,主要是不灵活,我不大喜欢,其实,只要想一下,既然js可以调用我的c++函数, 说明js可以认识c++函数,那么我的c++函数一定能通过相逆的方式认识JS函数, 也许直接通过回调函数即可完成, 没错, 下面我要讲的就是回调函数。


3、回调函数。此法的强大之处在于,主要你能调用我的C++函数, 我就能调用你给的回调函数, 此法的好处:简单、通用。

上代码:

新建一个ATL工程, 添加ATL简单对象CB,给CB添加接口SetCallBack、Test、Test1


// CB.cpp : CCB 的实现

#include "stdafx.h"
#include "CB.h"
#include <atlstr.h>
#include <dispex.h>


// CCB
IDispatch* s_spCallback;//手动添加, 用来保存js传过来的回调函数

STDMETHODIMP CCB::SetCallBack(VARIANT scriptcb)
{
	// TODO: 在此添加实现代码
	if (scriptcb.vt == VT_DISPATCH)
    {
        s_spCallback = scriptcb.pdispVal;
    }
	return S_OK;
}

STDMETHODIMP CCB::Test(LONG l) //测试回调函数
{
	// TODO: 在此添加实现代码
	CComVariant avarParams[1];
    avarParams[0] = l; //指定回调函数的参数
    DISPPARAMS params = { avarParams, NULL, 1, 0 };
    if(s_spCallback)
    {
        HRESULT hr = s_spCallback->Invoke(0, 
            IID_NULL, 
            LOCALE_USER_DEFAULT, 
            DISPATCH_METHOD, 
            ¶ms, NULL, NULL, NULL);
    }
	return S_OK;
}

STDMETHODIMP CCB::Test1(VARIANT v)
{
	// TODO: 在此添加实现代码
	//CString str;
	//str.Format(_T("%d"), v.vt);
	//::MessageBox(NULL, str, _T(""), 0);

	
	CComQIPtr<IDispatchEx> pParamEx = v.pdispVal;
	if( !pParamEx )
		return S_OK;

	DISPID dispid;
	DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};

	HRESULT hr = pParamEx->GetNextDispID(fdexEnumAll, DISPID_STARTENUM, &dispid);
	while (hr == NOERROR)
	{
		BSTR bstrName = NULL;
		VARIANT var;
		hr = pParamEx->GetMemberName(dispid, &bstrName);
		 pParamEx->InvokeEx(dispid, LOCALE_USER_DEFAULT,
         DISPATCH_PROPERTYGET, &dispparamsNoArgs, 
         &var, NULL, NULL);
		 ::MessageBox(NULL, var.bstrVal, _T(""), 0);
		SysFreeString(bstrName);

		hr = pParamEx->GetNextDispID(fdexEnumAll, dispid, &dispid);
	}

	return S_OK;
}




新建一个js脚本:

function callback(i)
{
  WScript.echo(i);
}
var obj = new ActiveXObject("TestJsCallBack.CB");
//var obj = new ActiveXObject("TestJsCallBack.CB.1")
obj.SetCallBack(callback)
obj.Test(456)//测试回调函数
var para = {"111":"111value","222":"222value"};
obj.Test1(para)//测试C++解析json对象



注:使用IDispatchEx接口:
在自定义类中添加头文件
#include "dispex.h"
在idl文件中 包含IDL文件

import "dispex.idl";


其实两种语言的交互无非要完成以下功能:1、能相互调用对方函数

2、能相互识别对方的自定义类型

从上述的Test1函数看出使用IdispatchEx可以解析js传给C++的自定义类型, 而js里面的这句话var obj = new ActiveXObject("TestJsCallBack.CB");告诉我们, C++将一个类暴露给了js


综上所述,IDiptch是不仅可以将C++接口暴露给脚本语言, 还可以解析脚本语言的函数或者对象, 实现二者相互调用






  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
QML与C++交互方法主要有以下几种: 1. 使用QObject::connect()函数连接QML和C++对象的信号和槽函数,实现数据的传递和交互。 2. 使用Q_INVOKABLE宏将C++函数声明为可在QML中调用的函数。这样,QML可以直接调用C++函数,实现数据的交互。 3. 使用Q_PROPERTY宏将C++对象的属性声明为可在QML中访问的属性。这样,QML可以直接访问C++对象的属性,实现数据的交互。 4. 使用QQmlContext类将C++对象注册到QML中,并在QML中访问这些对象。这样,QML可以直接访问C++对象,实现数据的交互。 下面是一个具体的例子,展示了如何在QML中访问C++对象的属性和函数。 C++代码: ``` // MyObject.h #include <QObject> class MyObject : public QObject { Q_OBJECT Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged) public: explicit MyObject(QObject *parent = nullptr); int value() const; void setValue(int value); signals: void valueChanged(); private: int m_value; }; // MyObject.cpp #include "MyObject.h" MyObject::MyObject(QObject *parent) : QObject(parent) { m_value = 0; } int MyObject::value() const { return m_value; } void MyObject::setValue(int value) { if (m_value != value) { m_value = value; emit valueChanged(); } } ``` QML代码: ``` import QtQuick 2.0 Item { width: 200 height: 200 Text { text: "Value: " + myObject.value } Slider { anchors.top: text.bottom from: 0 to: 100 value: myObject.value onValueChanged: myObject.value = value } Connections { target: myObject onValueChanged: text.text = "Value: " + value } Component.onCompleted: { console.log("Value:", myObject.value) } } ``` 在这个例子中,我们创建了一个名为MyObject的C++对象,并将其注册到QML中。MyObject类有一个名为value的属性和一个名为setValue的槽函数,用于设置属性值。在QML中,我们创建一个Slider和一个Text组件,用于显示和修改MyObject的value属性。我们还使用Connections组件将MyObject的valueChanged信号与Text的text属性绑定,以使其能够自动更新。最后,在Component.onCompleted信号处理程序中,我们打印MyObject的value属性的值,以验证其已成功从C++对象传递到QML界面。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值