Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to Pass TypeScript Number Array to C++? #1

Open
chhsgithub opened this issue Aug 12, 2023 · 6 comments
Open

How to Pass TypeScript Number Array to C++? #1

chhsgithub opened this issue Aug 12, 2023 · 6 comments

Comments

@chhsgithub
Copy link

chhsgithub commented Aug 12, 2023

Hello,

I am currently working on a project where I need to pass an array of numbers from TypeScript to C++. I couldn't find any clear documentation or examples related to this.

typescript:
let numArray: number[] = [0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5 ];

cpp:
std::vector parser(std::vector input){
for (int i = 0; i < input.size(); i++)
{
input[i]++;
}
return input;
}

I would like to know how I can pass this numArray to a C++ function and access its elements.

Questions:
Is there any recommended method to do this?
Are there any data type constraints or considerations I should be aware of while passing the array?
Any guidance or reference to documentation would be greatly appreciated. Thank you in advance!

@chexiongsheng
Copy link
Contributor

chexiongsheng commented Aug 14, 2023

Because pesapi does not yet support arrays (I will add array support to pesapi later), to achieve your requirement, you need to switch to using the v8 api by adding the PES_EXTENSION_WITH_V8_API macro in the compilation.
Then do the following two things: 1. Specialize the template of puerts::v8_impl::Converter to implement the mutual conversion between std::vector<T> and js arrays; 2. Generate std::vector<T> in *.d.ts by specializing the template of puerts::ScriptTypeName.

the following code show how to do:
std_container.zip

@chexiongsheng
Copy link
Contributor

I had add arrays support for pesapi, full extension for std::vector to js array is:

vector_to_array.h:

#pragma once

#include <vector>
#include "Binding.hpp"

namespace puerts
{
#ifdef PES_EXTENSION_WITH_V8_API
namespace v8_impl
{
template <typename T>
struct Converter<std::vector<T>>
{
    static v8::Local<v8::Value> toScript(v8::Local<v8::Context> context, std::vector<T> value)
    {
        auto ret = v8::Array::New(context->GetIsolate());
        for (size_t i = 0; i < value.size(); i++) {
            (ret->Set(context, i, Converter<T>::toScript(context, value[i]))).Check();
        }
        return ret;
    }

    static std::vector<T> toCpp(v8::Local<v8::Context> context, const v8::Local<v8::Value>& value)
    {
        std::vector<T> ret;
        if (value->IsArray()) {
            auto arr = value.As<v8::Array>();
            for (size_t i = 0; i < arr->Length(); i++) {
                ret.push_back(Converter<T>::toCpp(context, arr->Get(context, i).ToLocalChecked()));
            }
        }
        return ret;
    }

    static bool accept(v8::Local<v8::Context> context, const v8::Local<v8::Value>& value)
    {
        return value->IsArray();
    }
};
}

#else
namespace pesapi_impl
{
template <typename T>
struct Converter<std::vector<T>>
{
    static pesapi_value toScript(pesapi_env env, std::vector<T> value)
    {
        auto ret = pesapi_create_array(env);
        for (size_t i = 0; i < value.size(); i++) {
            pesapi_set_property_uint32(env, ret, i, Converter<T>::toScript(env, value[i]));
        }
        return ret;
    }

    static std::vector<T> toCpp(pesapi_env env, pesapi_value value)
    {
        std::vector<T> ret;
        if (pesapi_is_array(env, value)) {
            uint32_t len = pesapi_get_array_length(env, value);
            for (size_t i = 0; i < len; i++) {
                ret.push_back(Converter<T>::toCpp(env, pesapi_get_property_uint32(env, value, i)));
            }
        }
        return ret;
    }

    static bool accept(pesapi_env env, pesapi_value value)
    {
        return pesapi_is_array(env, value);
    }
};
}
#endif

template <typename T>
struct ScriptTypeName<std::vector<T>>
{
    static constexpr auto value()
    {
        return ScriptTypeName<T>::value() + internal::Literal("[]");
    }
};

}

@836454543
Copy link

是不是每次交互都需要动态生成对应的C++、js对象?,对于大容器会不会性能很低

@chexiongsheng
Copy link
Contributor

chexiongsheng commented Oct 23, 2023

是不是每次交互都需要动态生成对应的C++、js对象?,对于大容器会不会性能很低

默认不是转js array,而是c++对象的指针。
这是他要求转js array,他这个要求还要写代码来实现(默认不用,声明即可),如果要转,大容器开销会大。

@836454543
Copy link

是不是每次交互都需要动态生成对应的C++、js对象?,对于大容器会不会性能很低

默认不是转js array,而是c++对象的指针。 这是他要求转js array,他这个要求还要写代码来实现(默认不用,声明即可),如果要转,大容器开销会大。

js中的数组和C++交互,开销小的简单示例有吗?我参考下

@chexiongsheng
Copy link
Contributor

是不是每次交互都需要动态生成对应的C++、js对象?,对于大容器会不会性能很低

默认不是转js array,而是c++对象的指针。 这是他要求转js array,他这个要求还要写代码来实现(默认不用,声明即可),如果要转,大容器开销会大。

js中的数组和C++交互,开销小的简单示例有吗?我参考下

参考这对UE里头TArray的处理,这个文件的UsingContainer和RegisterTArray宏:
https://github.com/Tencent/puerts/blob/master/unreal/Puerts/Source/JsEnv/Public/UEDataBinding.hpp

这两个宏的使用看这里:https://github.com/chexiongsheng/puerts_unreal_demo/blob/master/Source/puerts_unreal_demo/UTGUnitTestCalleeWrap.cpp

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants