C++ Linking and running LuaJit compiled files with loadbuffer and runbuffer - c++

I have compiled test.lua with LuaJit into test.obj and test.h. How do I correctly use the loadBuffer or runBuffer functions that I have? All I need to find out is basically how to place test.lua, test.obj and test.h into the command but I just cant, Ive tried hundreds of ways but nothing seems to work. I have stripped some other functions off from main and so forth that it would just leave the problem visible and not other things that work just fine.
C++: This is the main
int main(int argc, const char* argv[])
{
std::vector<std::string> args(argv, argv + argc);
g_lua.loadBuffer("test.lua", "test.obj")
// I have tried both, runBuffer and loadBuffer but I just cant get it right, it always fails.
}
Here is the loadBuffer function:
void LuaCodes::loadBuffer(const std::string& buffer, const std::string& source)
{
int ret = luaL_loadbuffer(L, buffer.c_str(), buffer.length(), source.c_str());
if(ret != 0)
throw LuaException(popString(), 0);
}
Here is the runBuffer function:
void LuaCodes::runBuffer(const std::string& buffer, const std::string& source)
{
loadBuffer(buffer, source);
safeCall(0, 0);
}
Here are the insides of test.h:
#define luaJIT_BC_test_SIZE 1186
static const char luaJIT_BC_test[] = {
27,76,74,1,2,154,9,2,0,12,0,47,0,151,1,52,0,0,0,55,0,1,0,52,1,2,0,55,1,3,1,62,
1,1,2,52,2,4,0,55,2,5,2,62,2,1,2,37,3,6,0,36,1,3,1,62,0,2,1,52,0,0,0,55,0,7,0,
52,1,8,0,55,1,9,1,37,2,10,0,62,1,2,0,61,0,0,1,52,0,0,0,55,0,7,0,52,1,4,0,55,1,
11,1,62,1,1,2,37,2,12,0,52,3,4,0,55,3,13,3,62,3,1,2,37,4,14,0,52,5,4,0,55,5,
15,5,62,5,1,2,37,6,16,0,52,7,4,0,55,7,17,7,62,7,1,2,37,8,18,0,52,9,4,0,55,9,
19,9,62,9,1,2,37,10,20,0,52,11,4,0,55,11,21,11,62,11,1,2,36,1,11,1,62,0,2,1,
52,0,2,0,55,0,22,0,52,1,2,0,55,1,3,1,62,1,1,2,37,2,23,0,36,1,2,1,41,2,2,0,62,
0,3,2,14,0,0,0,84,0,4,128,52,0,0,0,55,0,24,0,37,1,25,0,62,0,2,1,52,0,2,0,55,0,
22,0,52,1,2,0,55,1,3,1,62,1,1,2,37,2,26,0,36,1,2,1,41,2,2,0,62,0,3,2,14,0,0,0,
84,0,4,128,52,0,0,0,55,0,24,0,37,1,27,0,62,0,2,1,52,0,2,0,55,0,22,0,52,1,2,0,
55,1,3,1,62,1,1,2,37,2,28,0,36,1,2,1,41,2,2,0,62,0,3,1,52,0,2,0,55,0,29,0,52,
1,4,0,55,1,5,1,62,1,1,0,61,0,0,1,52,0,2,0,55,0,30,0,37,1,31,0,37,2,32,0,41,3,
2,0,62,0,4,1,52,0,33,0,55,0,34,0,37,1,35,0,62,0,2,1,52,0,36,0,55,0,37,0,62,0,
1,1,52,0,36,0,55,0,38,0,39,1,99,0,62,0,2,1,52,0,36,0,55,0,39,0,37,1,40,0,62,0,
2,1,52,0,36,0,55,0,39,0,37,1,41,0,62,0,2,1,52,0,36,0,55,0,38,0,39,1,243,1,62,
0,2,1,52,0,36,0,55,0,39,0,37,1,42,0,62,0,2,1,52,0,36,0,55,0,38,0,39,1,231,3,
62,0,2,1,52,0,36,0,55,0,39,0,37,1,43,0,62,0,2,1,52,0,36,0,55,0,38,0,39,1,15,
39,62,0,2,1,37,0,31,0,52,1,4,0,55,1,5,1,62,1,1,2,37,2,44,0,36,0,2,0,52,1,2,0,
55,1,45,1,16,2,0,0,62,1,2,2,15,0,1,0,84,2,3,128,52,1,46,0,16,2,0,0,62,1,2,1,
71,0,1,0,11,100,111,102,105,108,101,15,102,105,108,101,69,120,105,115,116,115,
7,114,99,19,103,97,109,101,95,105,110,116,101,114,102,97,99,101,11,99,108,105,
101,110,116,12,103,97,109,101,108,105,98,12,99,111,114,101,108,105,98,23,101,
110,115,117,114,101,77,111,100,117,108,101,76,111,97,100,101,100,20,97,117,
116,111,76,111,97,100,77,111,100,117,108,101,115,20,100,105,115,99,111,118,
101,114,77,111,100,117,108,101,115,14,103,95,109,111,100,117,108,101,115,17,
47,99,111,110,102,105,103,46,111,116,109,108,9,108,111,97,100,14,103,95,99,
111,110,102,105,103,115,11,46,111,116,112,107,103,6,47,25,115,101,97,114,99,
104,65,110,100,65,100,100,80,97,99,107,97,103,101,115,22,115,101,116,117,112,
85,115,101,114,87,114,105,116,101,68,105,114,9,109,111,100,115,56,85,110,97,
98,108,101,32,116,111,32,97,100,100,32,109,111,100,117,108,101,115,32,100,105,
114,101,99,116,111,114,121,32,116,111,32,116,104,101,32,115,101,97,114,99,104,
32,112,97,116,104,46,12,109,111,100,117,108,101,115,53,85,110,97,98,108,101,
32,116,111,32,97,100,100,32,100,97,116,97,32,100,105,114,101,99,116,111,114,
121,32,116,111,32,116,104,101,32,115,101,97,114,99,104,32,112,97,116,104,46,
10,102,97,116,97,108,9,100,97,116,97,18,97,100,100,83,101,97,114,99,104,80,97,
116,104,17,103,101,116,66,117,105,108,100,65,114,99,104,15,32,102,111,114,32,
97,114,99,104,32,17,103,101,116,66,117,105,108,100,68,97,116,101,16,41,32,98,
117,105,108,116,32,111,110,32,19,103,101,116,66,117,105,108,100,67,111,109,
109,105,116,7,32,40,21,103,101,116,66,117,105,108,100,82,101,118,105,115,105,
111,110,10,32,114,101,118,32,15,103,101,116,86,101,114,115,105,111,110,6,32,
12,103,101,116,78,97,109,101,42,61,61,32,97,112,112,108,105,99,97,116,105,111,
110,32,115,116,97,114,116,101,100,32,97,116,32,37,98,32,37,100,32,37,89,32,37,
88,9,100,97,116,101,7,111,115,9,105,110,102,111,9,46,108,111,103,19,103,101,
116,67,111,109,112,97,99,116,78,97,109,101,10,103,95,97,112,112,15,103,101,
116,87,111,114,107,68,105,114,16,103,95,114,101,115,111,117,114,99,101,115,15,
115,101,116,76,111,103,70,105,108,101,13,103,95,108,111,103,103,101,114,0
};

For luaL_loadbuffer (and hence LuaCodes::loadBuffer) the 1st argument should be a string containing the bytecode and the 2nd argument should be a human-readable name (e.g. the filename that the bytecode was compiled from.)
Try:
#include "test.h"
// ...
int main(int argc, const char* argv[])
{
// ...
std::string bytecode(luaJIT_BC_test, luaJIT_BC_test_SIZE);
g_lua.loadBuffer(bytecode, "#test.lua")
}

Related

How to get C/C++ module information with libclang

I am trying to use the module functionalities from libclang. Here is the context:
I have a clang module defined and a source file that call it:
module.modulemap
module test {
requires cplusplus
header "test.h"
}
test.h :
#pragma once
static inline int foo() { return 1; }
test.cpp :
// Try the following command:
// clang++ -fmodules -fcxx-modules -fmodules-cache-path=./cache_path -c test.cpp
// If you see stuff in the ./cache_path directory, then it works!
#include "test.h"
int main(int, char **) {
return foo();
}
cache_path is at first empty then after the command I can see stuff in it so this is working.
My problem is when I try to use libclang to parse the test.cpp file in order to get informations about module:
#include <stdio.h>
#include "clang-c/Index.h"
/*
compile with:
clang -lclang -o module_parser module_parser.c
*/
static enum CXChildVisitResult
visitor(CXCursor cursor, CXCursor parent, CXClientData data)
{
CXSourceLocation loc;
CXFile file;
CXString module_import;
CXModule module;
CXString module_name;
CXString module_full_name;
unsigned line;
unsigned column;
unsigned offset;
if (clang_getCursorKind(cursor) == CXCursor_ModuleImportDecl)
{
loc = clang_getCursorLocation(cursor);
clang_getSpellingLocation(loc,
&file,
&line,
&column,
&offset);
module_import = clang_getCursorSpelling(cursor);
printf("Module import dec at line: %d \"%s\"\n", line, clang_getCString(module_import));
clang_disposeString(module_import);
}
module = clang_Cursor_getModule(cursor);
module_name = clang_Module_getName(module);
module_full_name = clang_Module_getFullName(module);
printf("Module name %s , full name %s\n", clang_getCString(module_name),
clang_getCString(module_full_name));
clang_disposeString(module_name);
clang_disposeString(module_full_name);
return CXChildVisit_Recurse; // visit complete AST recursivly
}
int main(int argc, char *argv[]) {
CXIndex Index = clang_createIndex(0, 1);
const char *args[] = { "-x",
"c++",
"-fmodules",
"-fcxxmodules"//,
"-fmodules-cache-path",
"cache_path"
};
CXTranslationUnit TU = clang_createTranslationUnitFromSourceFile(Index,
"test.cpp",
6,
args,
0,
0);
clang_visitChildren(clang_getTranslationUnitCursor(TU), visitor, 0);
clang_disposeTranslationUnit(TU);
clang_disposeIndex(Index);
return 0;
}
The output of this code is :
...
Module name , full name
Module name , full name
Module name , full name
Module name , full name
Module name , full name
...
First it seems that clang doesn't detect any cursor of the kind CXCursor_ModuleImportDecl and then at any momment it find a valid module.
What am I doing wrong?

QtConcurrent::mappedReduced

to improve my program, i want to use Qtconcurrent to parallelize my audio process.
Unfortunately, i have many errors and i don't know why ...
In my *.pro : QT += concurrent
I use minGW with Qt 5.3.1 and when i try to build, the compiler said "forming reference to void" (qvector.h).
Here my main code :
void Reduce(QString& result, const QString& txt){ result += txt;}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QFuture<QString> res = QtConcurrent::mappedReduced(wavSoundsList, &BenchFFT::process, Reduce, QtConcurrent::OrderedReduce);
res.waitForFinished();
qDebug("%s",qPrintable(res.result()));
return a.exec();
}
and my class :
class BenchFFT
{
public:
BenchFFT();
QString process(const QString &wavFile);
private:
QString soundsPath;
QStringList wavSoundsList;
//Audio file
bool OpenWav(const QString WavPath, SndfileHandle &file);
//FFT
bool ComputeFFT(SndfileHandle file);
double Blackman(int x, int iWindowSize);
//Intel IPP7
IppsFFTSpec_R_64f * pFFTSpec;
Ipp64f* data; // source FFT
Ipp64fc* fftResult; // dest FFT
};
if someone can explain me my mistakes.thx :)
Edit : now i don't have build error with this modification
QFuture<QString> res = QtConcurrent::mappedReduced(wavSoundsList, std::tr1::bind(&BenchFFT::process, BenchFFT(), std::tr1::placeholders::_1), &Reduce, QtConcurrent::OrderedReduce);
but my program crashed .....

Calling a c function from lua 5.2 generates a syntax error

I've been trying to get lua scripting working for a small game I'm working on, but lua seems to be more trouble than its worth. After much googling and hair tearing, I managed to get simple scripts running but quickly hit a wall. C functions don't seem to want to bind to lua, or at least don't want to run after binding. g++ compiles the c code without incident but the lua interpreter generates this syntax error:
LUA ERROR: bin/lua/main.lua:1: syntax error near 'getVersion'
My C(++) code:
#include <lua.hpp>
static const luaL_Reg lualibs[] =
{
{"base", luaopen_base},
{"io", luaopen_io},
{NULL, NULL}
};
void initLua(lua_State* state);
int getVersion(lua_State* state);
int main(int argc, char* argv[])
{
lua_State* state = luaL_newstate();
initLua(state);
lua_register(state, "getVersion", getVersion);
int status = luaL_loadfile(state, "bin/lua/main.lua");
if(status == LUA_OK){
lua_pcall(state, 0, LUA_MULTRET, 0);
}else{
fprintf(stderr, "LUA ERROR: %s\n", lua_tostring(state, -1));
lua_close(state);
return -1;
}
lua_close(state);
return 0;
}
void initLua(lua_State* state)
{
const luaL_Reg* lib = lualibs;
for (; lib->func != NULL; lib ++)
{
luaL_requiref(state, lib->name, lib->func, 1);
lua_settop(state, 0);
};
delete lib;
}
int getVersion(lua_State* state)
{
lua_pushnumber(state, 1);
return 1;
};
The Lua code:
print getVersion()
print is a function. Since its argument is neither a table constructor nor a string literal, you have to call it using ():
print(getVersion())
Read the funny manual here.

boost test case from dll access violation

I want to start Boost test case from dll under Windows RT. I built test case as dll via the Visual Studio command prompt using the following comandline:
cl.exe /EHsc /D_USRDLL /D_WINDLL /LDd ~location\testcase.cpp ~library location\libboost_unit_test_framework-vc110-mt-sgd-1_53.lib /link /DLL /OUT:~output directory\testcase.dll
placed it into my application’s folder and set property "Content" to "true". After launching of my application I have the following error:
Unhadled exception at the 0x00B9AF16 in TestApp.exe: 0xC0000005: Access violation reading location 0x00000000
Top of the call stack is below:
> TestApp.exe!boost::unit_test::framework::get(unsigned long id, boost::unit_test::test_unit_type t) Line 388 C++
TestApp.exe!boost::unit_test::framework::get(unsigned long id) Line 73 C++
TestApp.exe!boost::unit_test::traverse_test_tree(unsigned long id, boost::unit_test::test_tree_visitor & V) Line 232 C++
TestApp.exe!boost::unit_test::traverse_test_tree(const boost::unit_test::test_suite & suite, boost::unit_test::test_tree_visitor & V) Line 207 C++
TestApp.exe!boost::unit_test::traverse_test_tree(unsigned long id, boost::unit_test::test_tree_visitor & V) Line 234 C++
TestApp.exe!boost::unit_test::framework::run(unsigned long id, bool continue_test) Line 403 C++
TestApp.exe!boost::unit_test::unit_test_main(boost::unit_test::test_suite * (int, char * *) * init_func, int argc, char * * argv) Line 185 C++
Here is the dll code (NOTE: If I place the same code directly into my source, it works fine):
void test_stat()
{
//some code there
}
extern "C" {
__declspec (dllexport) test_suite* init_unit_test_suite( int argc, char* argv[] )
{
test_suite *test = BOOST_TEST_SUITE("test name");
test->add(BOOST_TEST_CASE(&test_stat));
return test;
}
}
Code of the application for launching of the test case:
boost::unit_test::test_suite* main_global_test_suite;
test_suite* init_unit_test_suite( int argc, char* argv[] ) {
return NULL; }
test_suite* run_global_test_suite (int, char* []) {
return main_global_test_suite;
}
HINSTANCE hMyDll;
typedef test_suite* (*PFN_MyFunction)(int,const char*);
PFN_MyFunction pfnMyFunction;
test_suite* rPtr;
if((hMyDll=::LoadPackagedLibrary(L"testcase", 0))==NULL)
{
return;
}
pfnMyFunction=(PFN_MyFunction)GetProcAddress(hMyDll,"init_unit_test_suite");
if (pfnMyFunction != NULL)
{
//just create fake arguments for the boost::unit_test::unit_test_main function call
char* argv[1024];
argv[0] = "Text";
rPtr = pfnMyFunction(1, NULL);
main_global_test_suite = rPtr;
const int error =
boost::unit_test::unit_test_main(&run_global_test_suite, 1, argv );
}
else
{
//handling code
}
FreeLibrary(hMyDll);
Is there any ideas how to solve the problem?
Check what console_test_runner is doing. This is command line application (part of Boost.Test), which intended to do just that - load and execute test units implemented in shared library. Also please make sure you tell UTF that you want to build dll: define BOOST_TEST_DYN_LINK.

Breaking down WinMain's cmdLine in old style main()'s arguments

I want to convert WinMain's cmdLine argument to argc and argv so I can use the argument parsing function I wrote for console applications.
This would be trivial except that I want to support "quotes" too. For example:
test.exe test1 test2 "testing testing"
should be
argv[0] = "test.exe"; argv[1] = "test1"; argv[2] = "test2"; argv[3] = "testing testing";
I realize that cmdLine doesn't have the program name (the argv[0]); this doesn't matter I can use a dummy value.
I was thinking of doing it with a regex, (("[^"]+")\s+)|(([^\s]+)\s*) I'm not sure how well it would work though.. Probably not very well? Is there any function to do that in the windows api? Thanks
If you are using Microsoft compiler, there are public symbols __argc, __argv and __wargv defined in stdlib.h. This also applies to MinGW that uses Microsoft runtime libraries.
Based on Denis K response
See: https://msdn.microsoft.com/library/dn727674.aspx
This adds Windows specific entrypoint to clasic startpoint of your app:
int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, char*, int nShowCmd)
{
return main(__argc, __argv);
}
CommandLineToArgvW looks like it would be helpful here.
If you want plain int argc, char** argv arguments you have to do it on your own.
void fetchCmdArgs(int* argc, char*** argv) {
// init results
*argc = 0;
// prepare extraction
char* winCmd = GetCommandLine();
int index = 0;
bool newOption = true;
// use static so converted command line can be
// accessed from outside this function
static vector<char*> argVector;
// walk over the command line and convert it to argv
while(winCmd[index] != 0){
if (winCmd[index] == ' ') {
// terminate option string
winCmd[index] = 0;
newOption = true;
} else {
if(newOption){
argVector.push_back(&winCmd[index]);
(*argc)++;
}
newOption = false;
}
index++;
}
// elements inside the vector are guaranteed to be continous
*argv = &argVector[0];
}
// usage
int APIENTRY WinMain(...) {
int argc = 0;
char** argv;
fetchCmdArgs(&argc, &argv);
}