I've got a path to my file defined this way:
const char* GROUND_TEXTURE_FILE = "objects/textures/grass.jpg";
And here is the function, which I use to load image:
bool loadTexImage2D(const string &fileName, GLenum target) {
...
// this will load image data to the currently bound image
// at first, we must convert fileName, for ascii, this method is fine?
wstring file(fileName.begin(), fileName.end());
if(ilLoadImage(file.c_str()) == IL_FALSE) { //here the program falls
What's wrong in my code? Why the program falls when ilLoadImage is called? I think, that file.c_str() should work fine as a wchar_t * type or not? Thanks for answer :)
As the author's said, you can do pretty anything without initializing the lib :D
#include <iostream>
#include <IL/il.h>
int main ()
{
std::string filename = "objects/textures/grass.jpg";
ilInit();
if (!ilLoadImage(filename.c_str())) {
std::cout << ilGetError() << std::endl;
return 1;
}
std::cout << ilGetInteger(IL_IMAGE_WIDTH) << std::endl;
std::cout << ilGetInteger(IL_IMAGE_HEIGHT) << std::endl;
return 0;
}
build:
g++ -Wall -pedantic --std=c++11 -g -o app main.cpp -lIL
Related
I've put together a very simple Lua engine but it seems to reject bytecode which works in the lua console. The uncompiled version works in the engine. Am I using luac wrong somehow?
I compile using the given command and run as './a.out'.
res/default.lua:
print("Setting up world structure.")
luac command:
luac -o res/default.lux res/default.lua
MWE:
#define SCRIPTDIR "res/"
#define THROW_IF_NONZERO(x,m) if((x)!=0) throw std::runtime_error(m);
#define THROW_IF_ZERO(x,m) if((x)==0) throw std::runtime_error(m);
extern "C" {
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
}
#include "sys/stat.h"
#include <string>
#include <system_error>
#include <iostream>
using std::string;
class Entity {
private:
lua_State *m_lua;
public:
Entity() : Entity(nullptr) { }
Entity(lua_State *lua) : m_lua{lua} { }
virtual ~Entity() { }
void load_and_run(string);
};
class WorldEntity : public Entity {
public:
WorldEntity(lua_State *lua) : Entity(lua) {
luaL_openlibs(lua);
}
~WorldEntity() { }
};
int main() {
lua_State *lua{nullptr};
try {
lua = luaL_newstate();
WorldEntity eWorld{lua};
eWorld.load_and_run("default"); // load default.lua/lux
} catch(std::exception &e) {
if (lua != nullptr) {
lua_close(lua);
}
std::cout << "Error: " << e.what() << std::endl;
}
return 0;
}
void Entity::load_and_run(string filename) {
THROW_IF_ZERO(m_lua, "Lua not started.");
filename = SCRIPTDIR + filename + ".lux";
struct stat sb;
int rc = stat(filename.c_str(), &sb);
if (rc == -1) {
filename.pop_back();
filename += "a";
rc = stat(filename.c_str(), &sb);
THROW_IF_NONZERO(rc, "File not found!");
}
std::cout << "File: " << filename << std::endl;
// Currently won't run compiled Lua scripts, not sure why.
rc = luaL_dofile(m_lua, filename.c_str());
THROW_IF_NONZERO(rc, "Could not load lua file.");
}
compile command:
gcc src/bug001mwe.cpp -std=c++14 -llua -lstdc++
correct output from script:
File: res/default.lua
Setting up world structure.
wrong output from bytecode:
File: res/default.lux
Error: Could not load lua file.
both files, output from lua console:
Setting up world structure.
What confused me was that it worked in the lua console but not in my program. I added a call to lua_tostring after the call to luaL_dofile, like this:
rc = luaL_dofile(m_lua, filename.c_str());
std::ostringstream ostr;
ostr << "Could not load lua file. ";
ostr << lua_tostring(m_lua, -1);
THROW_IF_NONZERO(rc, ostr.str());
The error string became:
Error: Could not load lua file. res/default.lux: version mismatch in precompiled chunk
What the heck?
Long story short, I had a previous version of Lua installed due to out of date package dependencies in some unrelated stuff. The older luac was intercepting the luac command and compiling to valid but incompatible bytecode. Uninstalled the unrelated packages which I didn't really need, and now everything works.
Moral of the story: always check for an error string on the Lua stack, it will (probably) tell you what's wrong.
So I'm trying to load a .dylib file at runtime in c++ and calling a function within it. It does not seem to be any problem loading the file but when i try to create a function-pointer to the "print" function it's result is NULL.
Here is my code:
/* main.cpp */
#include <iostream>
#include <string>
#include <dlfcn.h>
#include "test.hpp"
int main(int argc, const char * argv[]) {
std::string path = argv[0];
std::size_t last = path.find_last_of("/");
// get path to execution folder
path = path.substr(0, last)+"/";
const char * filename = (path+"dylibs/libtest.dylib").c_str();
// open libtest.dylib
void* dylib = dlopen(filename, RTLD_LAZY);
if (dylib == NULL) {
std::cout << "unable to load " << filename << " Library!" << std::endl;
return 1;
}
// get print function from libtest.dylib
void (*print)(const char * str)= (void(*)(const char*))dlsym(dylib, "print");
if (print == NULL) {
std::cout << "unable to load " << filename << " print function!" << std::endl;
dlclose(dylib);
return 2;
}
// test the print function
print("Herro Word!");
dlclose(dylib);
return 0;
}
test dylib headerfile
/* test.hpp */
#ifndef test_hpp
#define test_hpp
void print(const char * str);
#endif
the dylib c++ file
#include <iostream>
#include "test.hpp"
void print(const char * str) {
std::cout << str << std::endl;
}
the output when running is:
unable to load /Users/usr/Library/Developer/Xcode/DerivedData/project/Build/Products/Debug/dylibs/libtest.dylib print function!
Program ended with exit code: 2
I am quite new to c++ and have never loaded dylibs before. Any help would be much appreciated!
Try qualifying the print function declaration with extern "C" to get around the name mangling that is likely going on.
Here's a nice article on the topic: http://www.tldp.org/HOWTO/C++-dlopen/theproblem.html (solution discussion on page following)
Alright, so I could have sworn this worked in my program earlier, but now I'm being driven mad by std::fstream. I just want to open a file from command line arguments, ie.
./main Program1.S
should open the file Program1.S and scan it.
Here is how I set up a open_file() function in my code:
#include <string>
#include <iostream>
#include <fstream>
void open_file(std::fstream &ifp, std::string file_name) {
ifp.open(file_name, std::ios::in | std::ios::out);
if(ifp.fail()) {
std::cout << "File not found." << std::endl;
exit(1);
}
}
void close_file(std::fstream &ofp) {
if(ofp.is_open()) {
ofp.close();
return;
}
std::cout << "This file is not currently open" << std::endl;
}
int main(int argc, char * argv[]) {
std::string in_name;
in_name = argv[1];
std::fstream ifp;
open_file(ifp, in_name);
// do some processing
close_file(ifp);
return 0;
}
Now, I compile my program using (unfortunately I am required to use c++03): g++ -g -std=c++03 -Wall -pedantic main.cpp -o main
Compilation works and provides no errors, but when running the program using: ./main Program1.S, it goes to File not found in open_file(). I even checked what was in argv[1] and it is definitely a file that is in the current working directory. Is there something wrong with the way I am doing this?
Check to make sure your file has been added to your project folder. Otherwise, you need to specify a file path within your computer ex. "/Mac HD/Documents/myfile". The program has no idea what to do with a external file name without its file path. Hope this helps.
I have next some project:
main.cpp
#include <iostream>
#include <cstddef>
#include <dlfcn.h>
int main()
{
void* handle = dlopen("./shared_libs/libshared.so", RTLD_LAZY);
if (NULL == handle)
{
std::cerr << "Cannot open library: " << dlerror() << '\n';
return -1;
}
typedef int (*foo_t)(const std::size_t);
foo_t foo = reinterpret_cast<foo_t>(dlsym(handle, "foo"));
const char* dlsym_error = dlerror();
if (dlsym_error)
{
std::cerr << "Cannot load symbol 'foo': " << dlsym_error << '\n';
dlclose(handle);
return -2;
}
std::cout << "call foo" << std::endl;
foo(10);
dlclose(handle);
return 0;
}
shared.cpp:
#include <cstddef>
#include <iostream>
extern "C"
{
int foo(const std::size_t size)
{
int b = size / size;
int* a = new int[size];
std::cout << "leaky code here" << std::endl;
}
}
and Makefile:
all:
g++ -fPIC -g -c shared.cpp
g++ -shared -o shared_libs/libshared.so -g shared.o
g++ -L shared_libs/ -g main.cpp -ldl
I use tcmalloc for debug this test program, which load dynamically libshared.so:foo and execute it.run command:
LD_PRELOAD=/usr/local/lib/libtcmalloc.so HEAPCHECK=normal ./a.out
The 1 largest leaks:
Using local file ./a.out.
Leak of 40 bytes in 1 objects allocated from:
# 7fe3460bd9ba 0x00007fe3460bd9ba
# 400b43 main
# 7fe346c33ec5 __libc_start_main
# 400999 _start
# 0 _init
Why I get address 0x00007fe3460bd9ba instead of line in foo function?
please help
P.s. I tried to use gdb with LD_PRELOAD=.../tcmalloc.so, but I get:
"Someone is ptrace()ing us; will turn itself off Turning perftools heap leak checking off"
Try removing dlclose call.
It's known issue that heap checker & profilers can't handle unloaded
shared objects.
Hey this is more of a question, i want to know if it is possible to modify code through GUI asking because i was asked to see if i could create a GUI where the user can change certain attributes. i.e an exmaple is below
start %= -(status)
> lexeme[elementV]
> -(lexeme[elementF])
> +(inboundGroup);
Above is part of my code which is Boost SPIRIT which parses Strings so for example would it be possible to change the + to a * or - etc
+ = One
- = optional
* = multiple
Do you think it would be possible to change that through a GUI i think it could be just not sure on how to do it?
Any help i will be very grateful
Thanks Shamari
Everything is possible in programming ;-)
For dynamic modification of a program during execution, there are several solutions :
Use a dynamic language like LUA
Use a plugin system with dynamic loading
Since you require C++ and Boost Spirit, I think the best solution is to generate a plugin on the fly and load it afterwards.
Your program will generate code, compile it into a shared library (.so) and then load and execute it. (Some people will find that dirty. It's insecure also. But it's simple and it works.)
Here is an exemple for linux : plugin.h :
#ifndef PLUGIN_H__
#define PLUGIN_H__
#ifdef __cplusplus
extern "C" {
#endif
int process();
typedef int (*plugin_process_fn_ptr)();
#ifdef __cplusplus
}
#endif
#endif // PLUGIN_H__
Note that we must use extern C or else, C++ name mangling will make it difficult to import symbols.
plugin.cpp :
#include "plugin.h"
#include <iostream>
using namespace std;
int process()
{
int return_value = 0;
#include "plugin_content.inc.cpp"
return return_value;
}
Note that I use a hack here, the code will be included from another file, "plugin_content.inc.cpp". The code from user will be put inside.
a script to build the plugin, "build_plugin.sh" :
#! /bin/sh
g++ -c -Wall -fPIC plugin.cpp -o plugin.o
gcc -shared -o libplugin.so plugin.o
Now the calling program, main.cpp :
#include <iostream>
#include <fstream> // to open files
#include <dlfcn.h> // C lib to load dynamic libs
#include "plugin.h"
using namespace std;
// load the plugin and call the process() function fom it
static int process_via_plugin()
{
int return_value = -1;
void *lib_handle(NULL);
char *error(NULL);
char *plugin_lib = "./libplugin.so";
lib_handle = dlopen(plugin_lib, RTLD_LAZY);
if (!lib_handle)
{
cerr << "Error loading lib " << plugin_lib << " : " << dlerror() << endl;
exit(1);
}
char *plugin_fn = "process";
plugin_process_fn_ptr fn = (plugin_process_fn_ptr)dlsym(lib_handle, plugin_fn);
error = dlerror();
if (error)
{
cerr << "Error finding lib " << plugin_fn << " : " << error << endl;
exit(1);
}
// call the function loaded from lib
return_value = (*fn)();
dlclose(lib_handle);
lib_handle = NULL; // useless but for good habits ^^
return return_value;
}
// build or rebuild the plugin,
// we must call it when we change the plugin code code
static int build_plugin(string code)
{
{
char *plugin_code_file = "plugin_content.inc.cpp";
ofstream plugin_code(plugin_code_file, ios::out);
plugin_code << code << endl;
}
system("build_plugin.sh");
return 0;
}
// our program
int main(int argc, char *argv[])
{
cout << "Hello World !" << endl;
string code = ""
"cout << \"Hello from plugin !\" << endl;"
"";
// build a first version of the plugin and call it
build_plugin(code);
process_via_plugin();
// now we modify the code (use a GUI here)
code = ""
"cout << \"Hello from plugin, updated !\" << endl;"
"";
// rebuild the plugin and call it again
build_plugin(code);
process_via_plugin();
// do it again as much as you want.
return 0;
}
Now, build your program :
g++ -Wall -rdynamic -ldl main.cpp
and execute it :
a.out
and you get :
Hello World !
Hello from plugin !
Hello from plugin, updated !
The code I give you is very basic. For example, we should check if the compilation of the plugin is successful and report errors to the user. Now it's up to you to add more stuff.