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 parse usertype in C++ side from sol::table? #308

Closed
spin-scenario opened this issue Jan 4, 2017 · 8 comments
Closed

How to parse usertype in C++ side from sol::table? #308

spin-scenario opened this issue Jan 4, 2017 · 8 comments

Comments

@spin-scenario
Copy link

The 'projection' is my binding function, and its return type is 'cd' (complex number). It seems I can successfully get the array table as follows:
local fid = {}
for i = 1, 1024 do
fid[i] = projection(i)
end
print(#fid)

Now I'd like to deal with the 'fid' table with C++.
cx_vec fft_1d(const sol::table& t) {
for (auto& kv : t) {
sol::object val = kv.second;
cout << val.as<cd>()<<"\n";
}
...
}

lua side:
local spec = fft_1d(fid)

But It failed at the data parsing (val.as<cd>()). Thanks for your help.

@spin-scenario
Copy link
Author

Other similar problems for me also include class, struct parsing in sol::table.

@ThePhD
Copy link
Owner

ThePhD commented Jan 4, 2017

What does "it failed at the data parsing (val.as<cd>()) mean? Is that a compile-time error? A runtime error? What is the runtime error? What does it say when you have #define SOL_CHECK_ARGUMENTS and other safety features turned on?

I need more information to help you, as that looks like valid code that should work just fine.

@ThePhD ThePhD added this to the Bugs.Damnit milestone Jan 4, 2017
@ThePhD ThePhD self-assigned this Jan 4, 2017
@spin-scenario
Copy link
Author

Thanks for your quick response.
It is a runtime error. The code was supposed to crash at the val.as<cd>().
After I added the #define SOL_CHECK_ARGUMENTS ahead of #include <sol.hpp>, and it throwed out an exception as follows:
5

My script was
2

That indicated the error should locate at local spec = fft_1d(fid).

This is my overloaded functions:
1
I believe that it should have nothing to do with the overloaded functions, because the function cx_vec fft_1d(const sol::table& t) was called (with ## output).
4

Thanks.

@ThePhD
Copy link
Owner

ThePhD commented Jan 4, 2017

Thanks for letting me know. I still have a questions or two to figure this out.

Did you provide a custom binding for "cd", or are you just using the plain binding? The error indicates that, somehow, the value for second is essentially a table: do you know if your projection function is returning a table that holds userdata, or a userdata itself? As I understand it, projection should be returning a single cd object, and that should be getting serialized to lua inside of that fid table and then taken out.

The ONLY thing I can think of as going wrong here is that the table t has more than just the projection information you put on it. So when you iterate over it, it gives you some key "whatever" that has a value of table. To further inspect what's going wrong, I would suggest printing out the key values to be sure there's no extra stuff being added to your table.

@spin-scenario
Copy link
Author

You are absolutely right!

1

Actually, I defined two projection functions, but the binding was the other.

2

So when I change the binding, everthing goes well. SORRY for my stupid. However, it indicates that the Sol is much more powerful. Thanks for your help!

@ThePhD
Copy link
Owner

ThePhD commented Jan 4, 2017

Yeah, you don't have to create bindings that specifically create Lua objects. sol2 handles any C++ type in the world, and serializes it as an "opaque pointer" kind of thing called a userdata (with member functions and variables, if you define them with new_usertype, see the tutorial and examples).

If you need to customize how cd is taken from and given to the Lua system through sol, you can also use customization points.

Good luck!

@ThePhD ThePhD closed this as completed Jan 4, 2017
@ThePhD
Copy link
Owner

ThePhD commented Jan 4, 2017

ONE FINAL WORD OF WARNING:

The iterators you use to walk through a sol::table are NOT guaranteed to iterate in numeric order, or ANY kind of order. They may iterate backwards, forwards, in the style of cuckoo-hashing, by accumulating a visited list while calling rand() to find the next target...

It is NOT something you should rely on. If you want to figure out the length of a table, call the length operation (int count = mytable.size(); using the sol API) and then iterate from 1 to count. This will save you some headaches in the future when the implementation decides not to iterate in numeric order.

@spin-scenario
Copy link
Author

Thanks for your suggestions, I have relpaced iterators with numeric indexing.

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

No branches or pull requests

2 participants