So I was trying to make a program that dynamically creates a dll file and loads it into the program and calls it.
Here is my code for
createFile:
void createFile(std::string data, std::string name) {
std::ofstream file;
name += ".cpp";
file.open(name,std::ofstream::out);
if (file.is_open()) {
file << data;
std::cout << "File saved successfully" << std::endl;
file.close();
}
else {
std::cout << "Error opening file" << std::endl;
exit(1);
}
}
compile:
void compile(std::string name) {
std::string temp;
temp = "c++.exe " + name + ".cpp -o dll/" + name + ".dll -shared -fPIC";
system(temp.c_str());
}
loadFunc:
typedef void (*function)(const char*);
void loadFunc(LPCSTR name, LPCSTR func) {
HMODULE temp;
function __cdecl myproc;
temp = LoadLibraryA(name);
if (temp != NULL) {
std::cout << "\nDll is loaded";
myproc = (function) GetProcAddress(temp, func);
if (myproc !=NULL)
{
std::cout << "\nFunction is loaded\n";
(myproc)("Somthing here");
}
// Free the DLL module.
FreeLibrary(temp);
}
}
The problem is when I compile a dll using visual studio 2019 it works just fine, but if I compile a dll file using gcc or c++ or g++ it doesn't load the dll. So I tried using dependency walker to see the difference between two dll files(one made with gcc and another with visual studio). I saw the file structures were different. dll made with gcc had larger size than the one made with visual studio. Can anyone help me with this?
Edit:
So after doing some trial and error, I have found that only dll files that have C libraries work. I don't know why. I tried using iostream earlier, but it always failed to load and on the other hand when I used stdio.h it worked fine.
dllfile.cpp(with iostream):
#ifdef __cpluplus
extern "C" {
#endif
#include <iostream>
__declspec(dllexport) void print(const char *x){
std::cout<<x<<std::endl;
}
#ifdef __cplusplus
}
#endif
dllfile.cpp(with stdio):
#ifdef __cpluplus
extern "C" {
#endif
#include <stdio.h>
__declspec(dllexport) void print(const char *x){
printf("%s",x);
}
#ifdef __cplusplus
}
#endif
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.
I am trying to dynamically load a dll. The dll is found but when I try to find the function, it won't work.
Main.cpp
#include <iostream>
#include "windows.h"
typedef void (__stdcall *f_funci)();
int main(){
HINSTANCE hGetProcIDDLL = LoadLibrary("C:\\users\\MyWin.dll");
if (!hGetProcIDDLL) {
std::cout << "could not load the dynamic library" << std::endl;
return 0;
}else{
std::cout << "Found the dll" << std::endl;
}
f_funci funci = (f_funci)GetProcAddress(hGetProcIDDLL, "printSomething");
if (!funci) {
std::cout << "could not locate the function" << std::endl;
}
return 0;
}
and the file for the dll :
MyWin.h
#define TEST
#ifndef TEST
#define MAKRO __declspec(dllexport) __stdcall
MAKRO void printSomething();
#endif
MyWin.cpp
#include "MyWin.h"
#include <iostream>
void printSomething(){
std::cout<<"Call the function dynamically"<<std::endl;
}
Compiled the dll the following way:
g++ MyWin.h MyWin.cpp -shared -o MyWin.dll
Would appreciate any help
Im trying to create a C DLL to extend my Lua script which I am using in a C++ application.
My DLL code is in "mylib.h":
#include <iostream>
#include "lua.hpp"
extern "C"
{
static int l_hello(lua_State *L) {
std::cout << "sup lol?" << std::endl;
return 0;
}
static const struct luaL_Reg mylib[] = {
{ "l_hello", l_hello },
{ NULL,NULL }
};
__declspec(dllexport) int luaopen_mylib(lua_State *L)
{
std::cout << "loading my lib" << std::endl;
luaL_newlib(L, mylib);
return 1;
}
}
I build the code mentioned above and put the DLL "mylib.dll" in the application debug folder. When I run the app the program crashes on
local mylib = require "mylib"
with the error "error loading module 'mylib' from file 'C:\Users\Username\Documents\Visual Studio 2015\Projects\Project1Tests\Debug\mylib.dll':
The specified module cant be found (translated from another language)."
How do I solve this problem?
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)
I am loading a DLL from an application and I want the DLL to be able to use a function implemented in the application. The definition of the function is put in a header and is included in the DLL. Can anyone tell me what I am doing wrong here or whether this can't be done? Thanks for any help.
App:
include <API.h>
extern "C" int Mult(int x, int y)
{
return x*y;
}
int main(int argc, char **argv)
{
if(argc <= 1)
return -1;
void * pHandle = dlopen(argv[1], RTLD_NOW);
if(pHandle == NULL)
{
cout << "Can't find DLL : " << argv[1] << endl;
cout << dlerror() << endl;
return -2;
}
else
cout << "DLL Loaded" << endl;
The API.h file:
#ifndef __APP_API__
#define __APP_API__
extern "C" int Mult(int x, int y);
#endif
And the DLL:
#include <API.h>
int Imp1::GetFunctionID()
{
return Mult(42, 42);
}
When run, this gives me the error:
Can't find DLL : ./ll.d.so
./ll.d.so: undefined symbol: Mult
Please help. Thanks
You should instruct your compiler to put all the symbols of your executable (App) in it's dynamic symbol table. Otherwise, as Marcus Lindblom said, the dependencies would be one way only. With g++, the option is -rdynamic.