Javascript用YC_cppLoad()函数以对象的方式调用C/C++源码

本文介绍了一种C/C++与JavaScript跨语言调用的方法,通过特定格式的C/C++源码,实现与JavaScript的交互。文章详细展示了如何在C/C++中定义函数并映射到JavaScript的方法和属性,包括数学计算、字符串操作等,以及如何从JavaScript调用这些功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    以这种方式调用c/c++源码,c/c++文件须满足一定的格式,提供指定的数据结构。
    下面的bird.cpp就是一个满足这种格式的c/c++文件。

#include "yc.h"
char  m_title[256] = "no value 无初始值";
int fibonacci(int kk)  //计算fibonacci数列的函数
{
    if(kk < 2)  return kk;
    return fibonacci(kk-2) + fibonacci(kk-1);
};

//实现Javascript语句: pGrass.fib(n)
void stdcall Grass_fib(YHTML *phtml,byte *obj_ptr,JSVAL *pJval,
                                                        int argnum,JSVAL *argval)
{
    int n = js_arg_double(0,argnum,argval,-1);  //宏js_arg_double在yc.h中定义
pJval->val = fibonacci(n);
    pJval->type = JS_double;
}

//实现Javascript语句: pGrass.pi()
void stdcall Grass_pi(YHTML *phtml,byte *obj_ptr,JSVAL *pJval,
                                                        int argnum,JSVAL *argval)
{
    pJval->wptr = L"PI: 3.1415926";
    pJval->len = wcslen(pJval->wptr);
    pJval->stype = JS_string_const;   //不释放 pJval->wptr, pJval->wptr可传递
}

//实现Javascript语句: pGrass.sin(val)
void stdcall Grass_sin(YHTML *phtml,byte *obj_ptr,JSVAL *pJval,
                                                        int argnum,JSVAL *argval)
{
    double pval = js_arg_double(0,argnum,argval);
pJval->val = sin(pval);
    pJval->type = JS_double;
}

//实现Javascript语句: pGrass.oneValue
void stdcall Grass_rd_oneValue(YHTML *phtml,byte *obj_ptr,JSVAL *pJval)
{
    pJval->wptr = YC_charToWide(&pJval->len,m_title);
    pJval->stype = JS_string;   //自动释放 pJval->wptr  pJval->wptr不能传递
}

//实现Javascript语句: pGrass.oneValue = val
void stdcall Grass_wr_oneValue(YHTML *phtml,byte *obj_ptr,JSVAL *pJval)
{
js_get_str(pJval);       //js_get_str宏在yc.h中定义,它把pJval转换为字符串
    YC_wideToCharEx(m_title,sizeof(m_title)/2,pJval->wptr,pJval->len);
}

//实现Javascript语句: pTree = pGrass.create()
void stdcall Grass_create(YHTML *phtml,byte *obj_ptr,JSVAL *pJval,
                                                        int argnum,JSVAL *argval)
{
    YCJIT->create_cppObject(phtml,pJval,&Tree_data);  //用Tree_data结构创建对象
}

//实现Javascript语句: pTree.plant(a,b,c,d,……)
void stdcall Tree_plant(YHTML *phtml,byte *obj_ptr,JSVAL *pJval,
                                                        int argnum,JSVAL *argval)
{
    for(int ii= pJval->val=0; ii<argnum; ii++)
                        pJval->val += js_get_double(&argval[ii]);
    pJval->type = JS_double;
}

//实现Javascript语句: pTree[n]
void stdcall Tree_rd_one(YHTML *phtml,byte *obj_ptr,JSVAL *pJval)
{
    pJval->val = pJval->aryind * 100 + .2019;  //n = pJval->aryind
    pJval->type = JS_double;
}

//实现Javascript语句: pTree.aname = val
void stdcall Tree_rd_var(YHTML *phtml,byte *obj_ptr,JSVAL *pJval)
{
    static wchar_t wibuf[1024] = L"天若有情天亦老 - ";
    wcscat(wibuf,YCJS->get_keyName(phtml,pJval->varword,&pJval->len));
    pJval->len = wcslen(wibuf);       //aname = pJval->varword
    pJval->wptr = wibuf;
    pJval->stype = JS_string_nofree;  //不释放 pJval->wptr, pJval->wptr不能传递
}

//定义对象pTree的方法
JS_EXT_METHOD Tree_method[] = {
                              { L"plant",     Tree_plant  },
                              0,
                              };
//定义对象pTree的属性
JS_EXT_ATTR Tree_attr[] = {
                          { JS_KEY_ARY,   Tree_rd_one,  }, //用数组下标访问属性
                          { JS_KEY_VAR,   Tree_rd_var,  }, //用指定名字访问属性
                          0,
                          };

//定义对象pGrass的方法
JS_EXT_METHOD Grass_method[] = {
                               { L"fib",    Grass_fib  },
                               { L"pi",     Grass_pi  },
                               { L"sin",    Grass_sin  },
                               { L"create", Grass_create },
                               0,
                               };
//定义对象pGrass的属性
JS_EXT_ATTR Grass_attr[] = {
                           { L"oneValue", Grass_rd_oneValue, Grass_wr_oneValue },
                           { 0 },
                           };

jsDATA Grass_data = { Grass_attr, Grass_method, L"Grass" }; //用于创建pGrass对象
jsDATA Tree_data = { Tree_attr, Tree_method, L"Tree" };    //用于创建pTree对象

void main(void **pObj)
{
    if((int)pObj < 1000)  //当独立运行本程序时, 有argc = pObj
      {
        printf("fib(32) = %d\n", fibonacci(35));
        return;
      }
    *pObj = &Grass_data;   //当Javascript调用本程序时,pObj用于获得对象数据
}

                      c/c++代码文件:bird.cpp

getbb();
function getbb()
{
    let pGrass = YC_cppLoad("bird.cpp")        //创建pGrass对象
    printf("pGrass = %s\n",pGrass)             //以字符串格式显示pGrass对象
    printf("pGrass.fib = %s\n",pGrass.fib)     //以字符串格式显示pGrass.fib方法
    printf("pGrass.fib(38) = %s\n",pGrass.fib(38))//执行bird.cpp函数pGrass.fib()

    printf("\npGrass.oneValue = %s\n",pGrass.oneValue) //取出pGrass属性oneValue
    pGrass.oneValue = 7.2019                   //设置pGrass属性oneValue为7.2019
    pGrass.oneValue += " - 远上寒山石径斜"     //自加pGrass属性oneValue
    pGrass.oneValue += " - 白云深处有人家"     //自加pGrass属性oneValue
    printf("pGrass.oneValue = %s\n\n",pGrass.oneValue)  //打印pGrass属性oneValue

    //指定 pi() 和 fib() 方法为全局变量, 属性(如:oneValue)不能指定为全局变量
    let pp = YC_cppLoad("bird.cpp","pi fib") //使pGrass方法fib和pi成为全局变量
    printf("pp === pGrass: %s\n",pp === pGrass)
    printf("pp.oneValue = %s\n", pp.oneValue)
    printf("fib(15) = %s\n",fib(15))
    printf("pi() = %s\n",pi())

    YC_cppLoad("bird.cpp","*")  //使 bird.cpp 的所有方法为全局变量
    printf("sin(pi/4) = %f\n\n", sin(pi().split(':')[1]/4))

    let pTree = pGrass.create();
    printf("pTree = pGrass.create() = %s\n",pTree)
    printf("pTree.plant = %s\n",pTree.plant)
    printf("pTree.plant(...) = %s\n",pTree.plant(1.1,2.02,3.003,4.0004,5.00005));
    printf("pTree[1976] = %16.4f\n", pTree[1976]);
    printf("pTree.aname = %36.17s\n", pTree.人间正道是沧桑);
}

                      Javascript代码文件:bee.js

编译:用YC命令: ycc bee.js 生成 bee.exe。
运行:在cmd界面执行bee.exe后,输出下列文字:
      pGrass = [object Grass]
      pGrass.fib = function fib{ [native code] }
      pGrass.fib(38) = 39088169

      pGrass.oneValue = no value 无初始值
      pGrass.oneValue = 7.2019 - 远上寒山石径斜 - 白云深处有人家

      pp === pGrass: true
      pp.oneValue = 7.2019 - 远上寒山石径斜 - 白云深处有人家
      fib(15) = 610
      pi() = PI: 3.1415926
      sin(pi/4) = 0.707107

      pTree = pGrass.create() = [object Tree]
      pTree.plant = function plant{ [native code] }
      pTree.plant(…) = 15.12345
      pTree[1976] = 197600.2019
      pTree.aname = 天若有情天亦老 - 人间正道是沧桑

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值