Binding LuaJIT to C++ with LuaBridge results in "PANIC: unprotected error" - c++

Windows 10 x64, MSVC 2017, LuaJIT 2.0.5.
I searched the web, but answers didn't help.
Basically I'm trying to follow this manual, except that I had to place #include <LuaBridge.h> after Lua includes, because otherwise it doesn't work saying that the LuaBridge should go after Lua includes.
Hovewher, I get following error: PANIC: unprotected error in call to Lua API (attempt to call a nil value).
I have no idea why. If you need more info - just say what.
#include "stdafx.h"
#include <iostream>
#include <lua.hpp>
#include <LuaBridge/LuaBridge.h>
using namespace luabridge;
using namespace std;
int main()
{
lua_State* L = luaL_newstate();
luaL_dofile(L, "script.lua");
luaL_openlibs(L);
lua_pcall(L, 0, 0, 0);
LuaRef s = getGlobal(L, "testString");
LuaRef n = getGlobal(L, "number");
string luaString = s.cast<string>();
int answer = n.cast<int>();
cout << luaString << endl;
cout << "And here's our number:" << answer << endl;
system("pause");
return 0;
}
script.lua:
testString = "LuaBridge works!"
number = 42

The code in the tutorial is faulty. lua_pcall has nothing to call because luaL_dofile and luaL_openlibs don't push a function onto the stack, so it tries to call nil and returns 2 (the value of the macro LUA_ERRRUN).
I verified this by changing the code from the tutorial thus and compiling with g++. I didn't get a PANIC error, for whatever reason; maybe because it was using Lua 5.3:
#include <iostream>
extern "C" {
# include "lua.h"
# include "lauxlib.h"
# include "lualib.h"
}
#include <LuaBridge/LuaBridge.h>
using namespace luabridge;
int main() {
lua_State* L = luaL_newstate();
luaL_dofile(L, "script.lua");
std::cout << "type of value at top of stack: " << luaL_typename(L, -1) << std::endl;
luaL_openlibs(L);
std::cout << "type of value at top of stack: " << luaL_typename(L, -1) << std::endl;
std::cout << "result of pcall: " << lua_pcall(L, 0, 0, 0) << std::endl; // Print return value of lua_pcall. This prints 2.
LuaRef s = getGlobal(L, "testString");
LuaRef n = getGlobal(L, "number");
std::string luaString = s.cast<std::string>();
int answer = n.cast<int>();
std::cout << luaString << std::endl;
std::cout << "And here's our number: " << answer << std::endl;
}
As you noticed, the code is also faulty because the Lua headers have to be included before the LuaBridge header!

Related

std::system_error occurs at Protobuf ParseFromZeroCopyStream()

I'm testing protobuf with zlib compression.
I wrote some c++ sample code using protobuf 3.8.0, but the following error occurred at calling ParseFromZeroCopyStream() at Ubuntu.
terminate called after throwing an instance of 'std::system_error'
what(): Unknown error -1
(core dumped)
what can I do?
I tried to replace ParseFromZeroCopyStream() with ParseFromBoundedZeroCopyStream().
That results in no core dump, but ParseFromBoundedZeroCopyStream() returned false.
test.proto
syntax = "proto2";
package test;
message Msg
{
required uint32 data = 1;
}
test.cc
#include <iostream>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
#include <google/protobuf/io/gzip_stream.h>
#include "test.pb.h"
using namespace std;
using namespace google::protobuf;
using namespace test;
int main(void)
{
Msg srcMsg;
srcMsg.set_data(1);
long sSize = srcMsg.ByteSizeLong();
cout << "SerializedSize = " << sSize << endl;
char * compressedMsg = new char[sSize];
io::ArrayOutputStream aos(compressedMsg, sSize);
io::GzipOutputStream gos(&aos);
long cSize;
if (srcMsg.SerializeToZeroCopyStream(&gos) == true)
{
gos.Close();
cSize = aos.ByteCount();
cout << "compression success : " << cSize << " bytes" << endl;
}
else
{
cout << "compression error" << endl;
return 1;
}
Msg targetMsg;
io::ArrayInputStream ais(compressedMsg, cSize);
io::GzipInputStream gis(&ais);
if (targetMsg.ParseFromZeroCopyStream(&gis) == false)
{
cout << "decompression error" << endl;
}
else
{
cout << "decompression success : " << targetMsg.ByteSizeLong() << " bytes" << endl;
cout << "data = " << targetMsg.data() << endl;
}
delete[] compressedMsg;
return 0;
}
I expect that decompression succeeds.
You will need to learn to use a debugger to investigate further why exactly this "unknown error: -1" is thrown - if possible.
That being said, unknown library errors is sometimes caused by a failed memory allocation or in rarer cases some other ressource constraint like failing to start a thread/process, etc.

Trying to compile example code from Octave's Standalone Programs example, getting segfault on first line

I am trying to learn how to embed Octave in my C++ code. When running the second example from here, the code compiles fine, but when running the code, a segmentation fault appears in the first line, when trying to initialize the interpreter. I'm not extremely adept at C++ but even when looking it up I can't find any answers.
The original code had octave::feval instead of feval, that threw a different, namespace error, so I just got rid of that and added the parse.h in the includes. I doubt this is at all related to the issue but that is a modification I did do.
#include <iostream>
#include <octave/oct.h>
#include <octave/octave.h>
#include <octave/parse.h>
#include <octave/interpreter.h>
int
main (void)
{
// Create interpreter.
octave::interpreter interpreter;
try
{
int status = interpreter.execute ();
if (status != 0)
{
std::cerr << "creating embedded Octave interpreter failed!"
<< std::endl;
return status;
}
octave_idx_type n = 2;
octave_value_list in;
for (octave_idx_type i = 0; i < n; i++)
in(i) = octave_value (5 * (i + 2));
octave_value_list out = feval ("gcd", in, 1);
if (out.length () > 0)
std::cout << "GCD of ["
<< in(0).int_value ()
<< ", "
<< in(1).int_value ()
<< "] is " << out(0).int_value ()
<< std::endl;
else
std::cout << "invalid\n";
}
catch (const octave::exit_exception& ex)
{
std::cerr << "Octave interpreter exited with status = "
<< ex.exit_status () << std::endl;
}
catch (const octave::execution_exception&)
{
std::cerr << "error encountered in Octave evaluator!" << std::endl;
}
return 0;
}
The actual output is supposed to be:
GCD of [10, 15] is 5
I am using Linux Ubuntu 18.04 with Octave 4.2.2
The documentation looked at is a different version than the version I have installed on my computer. I have 4.2, but I was looking at 4.4 docs, which has different code for the task I was trying to accomplish.

Function pointer obtained from GetProcAddress crashes the program if it uses the stdlib

I'm trying to dynamically load a dll and call a function from it at runtime. I have succeeded in getting a working pointer with GetProcAddress, but the program crashes if the function from the dll uses the stdlib. Here's the code from the executable that loads the dll:
#include <iostream>
#include <windows.h>
typedef int (*myFunc_t)(int);
int main(void) {
using namespace std;
HINSTANCE dll = LoadLibrary("demo.dll");
if (!dll) {
cerr << "Could not load dll 'demo.dll'" << endl;
return 1;
}
myFunc_t myFunc = (myFunc_t) GetProcAddress(dll, "myFunc");
if (!myFunc) {
FreeLibrary(dll);
cerr << "Could not find function 'myFunc'" << endl;
return 1;
}
cout << "Successfully loaded myFunc!" << endl;
cout << myFunc(3) << endl;
cout << myFunc(7) << endl;
cout << myFunc(42) << endl;
cout << "Successfully called myFunc!" << endl;
FreeLibrary(dll);
return 0;
}
Here's code for the dll that actually works:
#include <iostream>
extern "C" {
__declspec(dllexport) int myFunc(int demo) {
//std::cout << "myFunc(" << demo << ")" << std::endl;
return demo * demo;
}
}
int main(void) {
return 0;
}
(Note that the main method in the dll code is just to appease the compiler)
If I uncomment the line with std::cout however, then the program crashes after the cout << "Sucessfully loaded myFunc!" << endl; line but before anything else gets printed. I know there must be some way to do what I want; what do I need to change for it to work?
As discussed in the comments, it turns out that the compiler's demands for a main function were hints that I was inadvertently making a an exe that decptively used the file extension dll, not an actual dll (because I didn't quite understand the compiler options I was using), which in some way messed up the dynamic loading of that assembly.

C++ Access violation exception when calling Matlab compiled function: null pointer mistake?

I've searched extensively but there seems not to be a satisfying answer to this question online. So I'm posting again this problem in case someone has found a solution.
I have written a C++ code that is supposed to call some Matlab code. I have compiled all my Matlab files using the following command:
mcc -N -W cpplib:libRTR2 -T link:lib RTR.m -v
I have included the header, DLL and LIB files created by above command in the 'Header Files'for my Visual Studio project. I have also includde mclmcrrt.lib, mclmcrrt.h and mclcppclass.h in the same.
Here is my C++ code:
#define BZZ_COMPILER 3
#include <stdint.h>
#include "./hpp/BzzMath.hpp"
#include "libRTR2.h"
#include <iostream>
#include "mclmcrrt.h"
#include "mclcppclass.h"
double RTRtest(BzzVector &x)
{
x(1);
mwArray out(1,1);
try {
// create input
double a[] = { x[1] };
mwArray in1(1, 1, mxDOUBLE_CLASS, mxREAL);
in1.SetData(a, 1);
// call function
RTR(1, out, in1);
// show result
std::cout << "objFun" << std::endl;
std::cout << out << std::endl;
double F[1];
out.GetData(F, 1);
for (int i = 0; i<1; i++) {
std::cout << F[i] << " " << std::endl;
}
}
catch (const mwException& e) {
std::cerr << e.what() << std::endl;
return -2;
}
catch (...) {
std::cerr << "Unexpected error thrown" << std::endl;
return -3;
}
// cleanup
return out;
}
int optim()
{
if (!mclInitializeApplication(NULL, 0)) {
std::cerr << "could not initialize the application" << std::endl;
mclGetLastErrorMessage();
return -1;
}
if (!libRTR2Initialize()) {
std::cerr << "Could not initialize the library" << std::endl;
return -1;
}
bzzFilePrint("BzzRobustMinimization.txt");
BzzVector Xmin(1, 2000.);
BzzVector Xmax(1, 5000.);
BzzVector X0(1, 2000.);
double F0 = RTRtest(X0);
BzzMinimizationRobust m(X0, F0, RTRtest, Xmin, Xmax);
m();
m.BzzPrint("Results");
libRTR2Terminate();
mclTerminateApplication();
}
int main()
{
mclmcrInitialize();
return mclRunMain((mclMainFcnType)optim, 0, NULL);
}
And when I try to debug it I obtain this error:
Access Violation Error
I know it is related probably to trying to pass a null pointer to one of my functions, but being no expert in C++ I'm struggling to find where the error lies. Any help is greatly appreciated!

LuaBridge assertion error

I've been going through some tutorials around luabridge for accessing c++ from lua but I've hit a problem I can't seem to find an answer to by searching google.
I've setup a sample program to run the script and access lua from c++, which works fine. But when I try to register a function in the global namespace it complains during runtime - compiling just fine.
#include <iostream>
#include <string>
#include "../LuaBridge/LuaBridge.h"
using namespace luabridge;
void printMessage(const std::string& s) {
std::cout << s << std::endl;
}
int main() {
lua_State* L = luaL_newstate();
getGlobalNamespace(L).addFunction("printMessage", printMessage);
luaL_dofile(L, "script.lua");
luaL_openlibs(L);
lua_pcall(L, 0, 0, 0);
LuaRef s = getGlobal(L, "testString");
LuaRef n = getGlobal(L, "number");
std::string luaString = s.cast<std::string>();
int answer = n.cast<int>();
std::cout << luaString << std::endl;
std::cout << "And here's our number:" << answer << std::endl;
}
So, this code with the addFunction call gives me this error
Lua: /home/linuxxon/Programming/kingdoms-online/Script/Lua/../LuaBridge/detail/Namespace.h:1080: luabridge::Namespace& luabridge::Namespace::addFunction(const char*, FP) [with FP = void (*)(const std::basic_string<char>&)]: Assertion `(lua_type(L, (-1)) == 5)' failed.
Withouth the addFunction call I get what is expected of the script.
Is there perhaps something obvious that I have missed, since I haven't found anything like it?
I would greatly appreciate all help!
The problem was that the
luaL_openlibs(L);
was after the script had been run. The problem was in the tutorial I was following, I encountered the same thing before in the beginning of my tries with lua.
It all works perfectly by calling it after creating the new lua state.