I did a first small test with LuaBridge 1 week ago and it worked to get an int from the script.
Now I deleted this code and tried to include Lua script in my game engine but it is no longer working.
I tried to go back to a basic code with this :
#include <iostream>
#include "lua5.2/lua.hpp"
#include "LuaBridge/LuaBridge.h"
using namespace luabridge;
int main()
{
lua_State* L;
L = luaL_newstate();
if(!luaL_loadfile(L, "../../script.lua"))
std::cout << "failed loading" << std::endl;
LuaRef s = getGlobal(L, "nmbr");
int luaInt = s.cast<int>();
std::cout << luaInt << std::endl;
return 0;
}
with this script
nmbr = 30
And it gives me :
PANIC: unprotected error in cell to Lua API (bad argument #2 (number expected, got nil))
Aborted (core dumped)
It the same when I tried to get a string or a function from the script and I have no idea what I'm doing wrong in this.
Thanks for your answers :)
From the documentation of luaL_loadfileex:
As lua_load, this function only loads the chunk; it does not run it.
What that means is that the script is loaded, but it haven't been executed so there is really no variable nmbr to get. You need to run the script first for the code to work (for eample by calling lua_call).
This is shown very well in the first simple example in this LuaBridge tutorial.
luaL_loadfile ~= luaL_dofile. You load the script and get it as function on the stack but don't execute it, so the global assignment doesn't happen.
Related
I couldn't come up with a better title, so feel free to give suggestions.
I tried to follow OneLoneCoder's tutorial on sound synthesizing, I'm only halfway through the first video and my code already throws an exception.
All I did was downloading his olcSoundMaker.h from his github, and copying the entry point:
#include <iostream>
#include "olcNoiseMaker.h"
double make_noise(double time)
{
return 0.5 * sin(440.0 * 2 * PI * time);
}
int main()
{
std::wcout << "Synthesizer, part 1" << std::endl;
std::vector<std::wstring> devices = olcNoiseMaker<short>::Enumerate();
for (auto d : devices)
{
std::wcout << "Found output device: " << d << std::endl;
}
olcNoiseMaker<short> sound(devices[0], 44100, 1, 8, 512);
sound.SetUserFunction(make_noise);
while (1) { ; }
return EXIT_SUCCESS;
}
In the video he runs this just fine; for me, it starts producing a sound, then after 60-80 iterations of the while (1) loop, it stops and raises this:
Unhandled exception thrown: write access violation.
std::_Atomic_address_as<long,std::_Atomic_padded<unsigned int> >(...) was 0xB314F7CC.
(from the <atomic> header file, line 1474.)
By stepping through the code with VS I didn't find out much, except that it happens at different times during every run, which may mean it has something to do with multithreading, but I'm not sure since I'm not very familiar with the topic.
I found this question which is similar, but even though it says [SOLVED] it doesn't show me the answers.
Anyone that can help to get rid of that exception?
I was using Dev C++ for coding c++ (for competitive programming, been doing it for a couple of months) but after a while I decided to try to do it on VSCode (terrible idea btw). Everything ended up working however when executing a program on the command prompt via Dev C++ it showed both the execution time and the return value of the main function like this:
Process exited after 4.962 seconds with return value 0
The problem is, when executing a c++ .exe file by normal means, these things are not shown and I don't even know where it comes from. Is there a program or a command that makes these show on the command prompt?
Edit: That comment solved my problem
"Execution time is not tracked by Windows. echo %errorlevel% prints the exit code."
A very rough example of achieving the requirement:
#include <iostream>
// to count time elapsed from beginning to end of the program
#include <chrono>
// for atexit() function
#include <cstdlib>
using namespace std::chrono;
// used globally, see the reason below of the answer
int i;
void onExit();
int main(void) {
int input;
// clock begins
steady_clock::time_point begin = steady_clock::now();
// --- SOME LONG PROGRAM ---
std::cin >> input;
// clock ends
steady_clock::time_point end = steady_clock::now();
// calculating the difference
long long diff = duration_cast<milliseconds>(end - begin).count();
// displaying the time
std::cout << "Process exited in " << diff / 1000.00 << 's' << std::endl;
// on exit of the program, this function will be executed
atexit(&onExit);
// supposing the return code is 5
i = 5;
return i;
}
// exit function to be executed before exit
void onExit() {
std::cout << "Exit code: " << i << std::endl;
}
This will output something like:
test // --- INPUT
Process exited in 4.383s
Exit code: 5
Notice that we've used the variable i globally since atexit()'s passed function must be returning void (i.e. nothing), that's the reason of not passing the i in the user-defined function onExit() and nothing else.
The definition of atexit() is as follows:
extern "C++" int atexit (void (*func)(void)) noexcept;
I am quite new to boost, as well as to multithreading and launching application using libraries. For my desired funcitonality, I was recommended by colleague to use boost::process library.
But the documentation to this part of boost is quite insufficient, so I could not determine which function suits my task best by documentation. I therefore started to try several functions there, but non has all the desired properties.
However there is one I cannot figure out, how to properly use. I cannot even compile it, let alone run it. And the function is boost::process::async_system. I could not find anywhere on internet some step-by-step guide on how to use this function and what individual components mean and do.
Could someone explain to me in detail the individual arguments and template arguments of the function ? Or provide a link to a detailed manual?
I like the examples here: https://theboostcpplibraries.com/boost.thread-futures-and-promises
For example, look at example 44.16, they clearly show how to use async:
#define BOOST_THREAD_PROVIDES_FUTURE
#include <boost/thread.hpp>
#include <boost/thread/future.hpp>
#include <iostream>
int accumulate()
{
int sum = 0;
for (int i = 0; i < 5; ++i)
sum += i;
return sum;
}
int main()
{
boost::future<int> f = boost::async(accumulate);
std::cout << f.get() << '\n';
}
Waiting happens at the get method, not before. You might use a non-waiting mechanism, too.
As for compiling, you need to first build boost. Building is explained in detail here: https://www.boost.org/doc/libs/1_62_0/more/getting_started/windows.html
Most parts of the library work header-only. For asio, building the binary libraries (also explained in the link) is necessary. In your project (i.e. visual studio projects, xcode project or just some make files), you need to set include and library headers of boost to use it. The link above helps with this as well.
I'm just ramping up on Boost.Process but the sample code I have working might be helpful here.
boost::process:async_system() takes 3 parameters: a boost::asio::io_context object, an exit-handler function, and the command you want to run (just like system(), and it can be either a single line or more than one arg).
After it's invoked, you use the io_context object from the calling thread to manage and monitor the async task - I use the run_one() method which will "Run the io_context object's event processing loop to execute at most one handler" but you can also use other methods to run for a duration etc.
Here's my working code:
#include <boost/process.hpp>
#include <iostream>
using namespace boost;
namespace {
// declare exit handler function
void _exitHandler(boost::system::error_code err, int rc) {
std::cout << "DEBUG async exit error code: "
<< err << " rc: " << rc <<std::endl;
}
}
int main() {
// create the io_context
asio::io_context ioctx;
// call async_system
process::async_system(ioctx, _exitHandler, "ls /usr/local/bin");
std::cout << "just called 'ls /usr/local/bin', async" << std::endl;
int breakout = 0; // safety for weirdness
do {
std::cout << " - checking to see if it stopped..." << std::endl;
if (ioctx.stopped()) {
std::cout << " * it stopped!" << std::endl;
break;
} else {
std::cout << " + calling io_context.run_one()..." << std::endl;
ioctx.run_one();
}
++breakout;
} while (breakout < 1000);
return 0;
}
The only thing my example lacks is how to use boost::asio::async_result to capture the result - the samples I've see (including here on slashdot) still don't make much sense to me, but hopefully this much is helpful.
Here's the output of the above on my system:
just called 'ls /usr/local/bin', async
- checking to see if it stopped...
+ calling io_context.run_one()...
- checking to see if it stopped...
+ calling io_context.run_one()...
VBoxAutostart easy_install pybot
VBoxBalloonCtrl easy_install-2.7 pyi-archive_viewer
((omitted - a bunch more files from the ls -l command))
DEBUG async exit error code: system:0 rc: 0
- checking to see if it stopped...
* it stopped!
Program ended with exit code: 0
I did a new installation of Eclipse Juno 32 bits, and a new installation of MinGW 32 bits, my platform is Windows 7 64 bits. When trying to debug a simple program I can watch very simple expressions, but everything more complicated gets me an error. For an example in the following program:
int main()
{
vector<int> vRings;
for(int i=0;i<50;i++) {
vRings.push_back(i%5);
}
//std::cout << "result:" << getRingNumber(vRings,vDiscs);
return 0;
}
In the watch window, watching vRings work normally, but trying to watch the content of the vector doesn't work:
Trying to watch vRings[0]:
Error: Multiple errors reported.\ Failed to execute MI command: -var-create - *
vRings[0] Error message from debugger back end: Could not find
operator[].\ Unable to create variable object
Trying to watch vRings.at(0):
vRings.at(0) Error: Multiple errors reported.\ Failed to execute MI
command: -var-create - * vRings.at(0) Error message from debugger back
end: Cannot evaluate function -- may be inlined\ Unable to create
variable object
What can I do to solve the problem?
You are trying to watch the result of a function call.
Both vRings.at() and vRings[] are functions (the latter an overloaded function) that return a reference to a value. In your case - an integer.
If you want to watch the value of vRings at index 0, you can try to assign it to a variable at some point, for example:
int main()
{
vector<int> vRings;
for(int i=0;i<50;i++) {
vRings.push_back(i%5);
}
int watchme = vRings.at(0);
//std::cout << "result:" << getRingNumber(vRings,vDiscs);
return 0;
}
Then you can watch the variable watchme.
I'm using gdb to debug some c++ code. At the moment the code I'm looking at iterates through an array of pointers, which are either a pointer to some object or a NULL pointer.
If I just display list[index]->member it'll complain when list[index] is null. Is there anyway to display the member only if list[index] is not null? I know you can set conditional breakpoints (condition <bp-num> <exp>) but I'm not sure how that'd help.
The code in question is:
for (int i=0;i<BSIZE*BSIZE;i++){
if (vms[i]==target) {valid=true; break;}
}
where vms is the array of pointers.
Since display accepts arbitrary expressions, you can try something like the following display command:
display (list[index]) ? list[index]->member : "null"
I'm not sure if that cleans things up well enough for what you want - you'll still get a display, but it won't be a complaint.
Basically the condition works like this:
#include <iostream>
int main() {
for (int i=0; i<10; ++i) {
std::cerr << i << std::endl;
}
}
You can debug it like this:
(gdb) break 5
Breakpoint 1 at 0x100000d0e: file foobar.cpp, line 5.
(gdb) condition 1 i==3
(gdb) r
Starting program: /private/tmp/foobar
Reading symbols for shared libraries ++. done
0
1
2
Breakpoint 1, main () at foobar.cpp:5
5 std::cerr << i << std::endl;