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.
Related
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
I try to test loading a c++ dll module in Lua using "require", below is the c++ module file
#include <stdio.h>
#include <iostream>
extern "C" {
#include "lua/lualib.h"
#include "lua/lauxlib.h"
#include "lua/lua.h"
__declspec(dllexport) int luaopen_mylib(lua_State* L);
}
using namespace std;
static int libFunc1(lua_State* L)
{
int n = lua_gettop(L);
printf("in myfunc stack, arg number: %d\n", n);
if (lua_isstring(L, -1))
{
std::cout << lua_tostring(L, -1) << std::endl;
}
else
{
std::cout << "invalid arg" << std::endl;
}
return 1;
}
static const struct luaL_Reg mylib[] = {{"func1", libFunc1}, {NULL, NULL}};
int luaopen_mylib(lua_State* L)
{
cout << "loading my lib" << endl;
luaL_newlib(L, mylib);
return 1;
}
I compiled this cpp file into dll using g++ in msys:
g++ -c -o mylib.o mylib.cpp
g++ -shared -o mylib.dll mylib.o -Llua -llua5.3.0
until now everything work fine, and I got the mylib.dll file too. but when I try to load the module, I got the error msg:
> require("mylib")
error loading module 'mylib' from file '.\mylib.dll':
找不到指定的程序。
stack traceback:
[C]: in ?
[C]: in function 'require'
stdin:1: in main chunk
[C]: in ?
the Chinese characters above mean:
The specified function could not be found.
I think the "specified function" mean the "luaopen_mylib", but the cpp file do have the function:luaopen_mylib, WHAT IS GOING WRONG?
It might be some name mangling problem. Try:
extern "C"
{
int luaopen_mylib(lua_State* L)
{
cout << "loading my lib" << endl;
luaL_newlib(L, mylib);
return 1;
}
}
//DLL Code
#include <stdio.h>
extern "C"
{
__declspec(dllexport) void DisplayHelloFromDLL()
{
printf("Hello from DLL !\n");
}
}
//Program Accessing DLL
#include<windows.h>
#include<iostream>
#include<conio.h>
typedef void (*DisplayHelloFromDLLFuncPtr)();
using namespace std;
int main()
{
HINSTANCE hGetProcIDDLL = LoadLibrary("L:\\C_Learning\\Library\\MyLib\\Debug\\MyLib.dll");
if (!hGetProcIDDLL)
{
cout << "\nCould Not The Library";
return EXIT_FAILURE;
}
else
{
cout << "\nDLL is Loaded";
}
DisplayHelloFromDLLFuncPtr LibMainEntryPoint=(DisplayHelloFromDLLFuncPtr)GetProcAddress(hGetProcIDDLL, "DisplayHelloFromDLL");
if (!DisplayHelloFromDLL)
{
cout << "\nCould not locate the function";
return EXIT_FAILURE;
}
cout << DisplayHelloFromDLL();
return EXIT_SUCCESS;
_getch();
return 0;
}
Code executes till cout statement in else condition.
Receive Error while compiling for Function in DLL.
Error received 'DisplayHelloFromDLL': undeclared identifier
Ran Depends.exe which confirms about the function availability in DLL address space.
DLL and Sample Program is compiled with 32-bit environment.
6.Program sole purpose is to call function C DLL and print Hello From DLL message.
Any Suggestions ?
You named the variable holding the "DisplayHelloFromDLL" function pointer as "LibMainEntryPoint":
DisplayHelloFromDLLFuncPtr LibMainEntryPoint=(DisplayHelloFromDLLFuncPtr)GetProcAddress(hGetProcIDDLL, "DisplayHelloFromDLL");
but then you try to use it with different name (DisplayHelloFromDLL):
if (!DisplayHelloFromDLL) ...
Be consistent with the variable names, and the code should work.
change it to:
DisplayHelloFromDLLFuncPtr DisplayHelloFromDLL=(DisplayHelloFromDLLFuncPtr)GetProcAddress(hGetProcIDDLL, "DisplayHelloFromDLL");
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 try to test loading a c++ dll module in Lua using "require", below is the c++ module file
#include <stdio.h>
#include <iostream>
extern "C" {
#include "lua/lualib.h"
#include "lua/lauxlib.h"
#include "lua/lua.h"
__declspec(dllexport) int luaopen_mylib(lua_State* L);
}
using namespace std;
static int libFunc1(lua_State* L)
{
int n = lua_gettop(L);
printf("in myfunc stack, arg number: %d\n", n);
if (lua_isstring(L, -1))
{
std::cout << lua_tostring(L, -1) << std::endl;
}
else
{
std::cout << "invalid arg" << std::endl;
}
return 1;
}
static const struct luaL_Reg mylib[] = {{"func1", libFunc1}, {NULL, NULL}};
int luaopen_mylib(lua_State* L)
{
cout << "loading my lib" << endl;
luaL_newlib(L, mylib);
return 1;
}
I compiled this cpp file into dll using g++ in msys:
g++ -c -o mylib.o mylib.cpp
g++ -shared -o mylib.dll mylib.o -Llua -llua5.3.0
until now everything work fine, and I got the mylib.dll file too. but when I try to load the module, I got the error msg:
> require("mylib")
error loading module 'mylib' from file '.\mylib.dll':
找不到指定的程序。
stack traceback:
[C]: in ?
[C]: in function 'require'
stdin:1: in main chunk
[C]: in ?
the Chinese characters above mean:
The specified function could not be found.
I think the "specified function" mean the "luaopen_mylib", but the cpp file do have the function:luaopen_mylib, WHAT IS GOING WRONG?
It might be some name mangling problem. Try:
extern "C"
{
int luaopen_mylib(lua_State* L)
{
cout << "loading my lib" << endl;
luaL_newlib(L, mylib);
return 1;
}
}