Dinamic loading Static linking on linux
Dinamic loading Static linking on linux
Hello,
I am building a portable aplication. On windows it is working great, and it is really simple, you got the dll, the lib and everything works perfect (or should).
Now on Linux, there is no IDE that handles shared objects for dummies. I managed to create a so that is loaded with wxDynamicLibrary. But now I want to build a library that is loaded dynamically but linked statically.
I have just no idea how to do it. I read some articles but was written with a step by step how to. I saw that I had to create the real name, the soname and the linker name and run ldconfig and many stuff like that but I didnt manage to understand it completly. If anyone could help with an explanation or link I'd appreciate. I am using OpenSuse 11.1 Gnome.
Thanks
I am building a portable aplication. On windows it is working great, and it is really simple, you got the dll, the lib and everything works perfect (or should).
Now on Linux, there is no IDE that handles shared objects for dummies. I managed to create a so that is loaded with wxDynamicLibrary. But now I want to build a library that is loaded dynamically but linked statically.
I have just no idea how to do it. I read some articles but was written with a step by step how to. I saw that I had to create the real name, the soname and the linker name and run ldconfig and many stuff like that but I didnt manage to understand it completly. If anyone could help with an explanation or link I'd appreciate. I am using OpenSuse 11.1 Gnome.
Thanks
What I meant is like windows that you have a dll and a lib. You can link your aplication to your .lib file so the application is aware of all the functions and classes exported by the dll.
On linux I only managed to load a shared object (.so) with wxDynamicLibrary. I didnt manage to link it to my application correctly so i could use all the exported functions. I think the problem is in my library creation method not my linking method. I am using MonoDevelop with g++ as my compiler. And here is how I compiled my library:
Compiling source to object files
g++ -MMD "/home/rodrigo/ActionLx/ActionRes/ActionRes/ACTIONRES.cpp" -g -fPIC -O0 -I/home/rodrigo/wxGTK-2.8.9/dinDebug/lib/wx/include/gtk2-ansi-debug-2.8 -I/home/rodrigo/wxGTK-2.8.9/include -I/home/rodrigo/wxGTK-2.8.9/contrib/include -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -D__WXDEBUG__ -D__WXGTK__ -DDEBUG -DMONODEVELOP -D_LINUX_ -I"/home/rodrigo/ActionLx/ActionRes/ActionRes/.prec/Debug" -c -o "/home/rodrigo/ActionLx/SharedObjects/ACTIONRES.o"
Generating shared object "libActionRes.so" from object files
g++ -shared -o "/home/rodrigo/ActionLx/SharedObjects/libActionRes.so" "/home/rodrigo/ActionLx/SharedObjects/ACTIONRES.o" "/home/rodrigo/ActionLx/SharedObjects/StdWx.o" -L/home/rodrigo/wxGTK-2.8.9/dinDebug/lib -pthread -Wl,-rpath,/home/rodrigo/wxGTK-2.8.9/dinDebug/lib -lwx_gtk2d_richtext-2.8 -lwx_gtk2d_aui-2.8 -lwx_gtk2d_xrc-2.8 -lwx_gtk2d_qa-2.8 -lwx_gtk2d_html-2.8 -lwx_gtk2d_adv-2.8 -lwx_gtk2d_core-2.8 -lwx_based_xml-2.8 -lwx_based_net-2.8 -lwx_based-2.8
Any clues?
On linux I only managed to load a shared object (.so) with wxDynamicLibrary. I didnt manage to link it to my application correctly so i could use all the exported functions. I think the problem is in my library creation method not my linking method. I am using MonoDevelop with g++ as my compiler. And here is how I compiled my library:
Compiling source to object files
g++ -MMD "/home/rodrigo/ActionLx/ActionRes/ActionRes/ACTIONRES.cpp" -g -fPIC -O0 -I/home/rodrigo/wxGTK-2.8.9/dinDebug/lib/wx/include/gtk2-ansi-debug-2.8 -I/home/rodrigo/wxGTK-2.8.9/include -I/home/rodrigo/wxGTK-2.8.9/contrib/include -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -D__WXDEBUG__ -D__WXGTK__ -DDEBUG -DMONODEVELOP -D_LINUX_ -I"/home/rodrigo/ActionLx/ActionRes/ActionRes/.prec/Debug" -c -o "/home/rodrigo/ActionLx/SharedObjects/ACTIONRES.o"
Generating shared object "libActionRes.so" from object files
g++ -shared -o "/home/rodrigo/ActionLx/SharedObjects/libActionRes.so" "/home/rodrigo/ActionLx/SharedObjects/ACTIONRES.o" "/home/rodrigo/ActionLx/SharedObjects/StdWx.o" -L/home/rodrigo/wxGTK-2.8.9/dinDebug/lib -pthread -Wl,-rpath,/home/rodrigo/wxGTK-2.8.9/dinDebug/lib -lwx_gtk2d_richtext-2.8 -lwx_gtk2d_aui-2.8 -lwx_gtk2d_xrc-2.8 -lwx_gtk2d_qa-2.8 -lwx_gtk2d_html-2.8 -lwx_gtk2d_adv-2.8 -lwx_gtk2d_core-2.8 -lwx_based_xml-2.8 -lwx_based_net-2.8 -lwx_based-2.8
Any clues?
Ok I managed to do it, the problem was I wasnt linking correctly to the library (dumb mistake). But now there is the problem is that it doesnt enter the OnInit function when the library is loaded.
I have no clues as to why this is happening, on windows it worked. Dont know if on linux the behaviour should be the same. Any clues?
Thanks
I have no clues as to why this is happening, on windows it worked. Dont know if on linux the behaviour should be the same. Any clues?
Thanks
Okay, I think you need to read a bit about programming under linux, expecting it to work like Windows is not enough
Windows has this idea that each shared lib comes with a static lib to hook it into the app; this idea is totally non-existent in pretty much all other systems (linux, *BSD, Mac OS X, ...) On these systems, you just link the dynamic library directly in using the -l flag (if you use gcc)
Windows has this idea that each shared lib comes with a static lib to hook it into the app; this idea is totally non-existent in pretty much all other systems (linux, *BSD, Mac OS X, ...) On these systems, you just link the dynamic library directly in using the -l flag (if you use gcc)
Not sure what you mean here; is the OnInit function in the main program or declared in the library? Maybe post some code. Also, what happens? You say OnInit doesn't enter; how do you see/detect that? Does it crash? Does it hang? etc.But now there is the problem is that it doesnt enter the OnInit function when the library is loaded.
I know i still trying to understand how linux works sometimes I get stuck on simple things.
The OnInit on the executable runs fine. But when i load my library I thought it was suposed to enter the shared object OnInit. At least on windows when the library got loaded into memory the OnInit function always ran before any other function. The reason I need this is because there are objects that I need to initialize before I can run the functions. To test i put a message box on OnInit and it never pops up. here is a brief code
header
That part that is windows only shouldnt matter now but I put it just to show it was working on windows.
The OnInit on the executable runs fine. But when i load my library I thought it was suposed to enter the shared object OnInit. At least on windows when the library got loaded into memory the OnInit function always ran before any other function. The reason I need this is because there are objects that I need to initialize before I can run the functions. To test i put a message box on OnInit and it never pops up. here is a brief code
Code: Select all
IMPLEMENT_APP_NO_MAIN(CACTIONRESApp)
// The one and only CACTIONRESApp object
bool CACTIONRESApp::OnInit(){
wxMessageBox("init");
}
#ifdef _WIN32
DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
wxApp::SetInstance(new CACTIONRESApp());
wxEntry(GetModuleHandle(NULL),NULL,NULL,SW_SHOW);
return true;
}
BOOL APIENTRY DllMain(HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
ThreadId = CreateThread(NULL,0,ThreadProc,NULL,0,NULL);
break;
case DLL_THREAD_ATTACH: break;
case DLL_THREAD_DETACH: break;
case DLL_PROCESS_DETACH:
wxEntryCleanup();
break;
}
return TRUE;
}
#endif //_WIN32
Code: Select all
class CACTIONRESApp : public wxApp
{
bool OnInit();
};
I added this main and it never entered
Sorry for the "should have studied more before trying to do it" questions, but I didnt find any page on google explaing how to set the entry point.
If you know any documentation that could help I'd appreciate
thanks
Code: Select all
int main(int argc, char **argv){
wxMessageBox("main");
wxEntry(argc,argv);
}
If you know any documentation that could help I'd appreciate
thanks
I am trying with something very simple to see if I can make it go through OnInit.
Here is the code for the executable
this would be the code for the linked shared object
If there is a way to make this code print "init" when the so is loaded it would solve all (actually just the most recent) of my problems
thanks
Here is the code for the executable
Code: Select all
using namespace std;
extern "C" void foo();
int main (int argc, char *argv[])
{
cout << "Hello world!" << endl;
foo();
return 0;
}
Code: Select all
#include "wx/wx.h"
#include <iostream>
// Add function definitions here
class MyApp : public wxApp{
bool OnInit();
};
IMPLEMENT_APP(MyApp)
bool MyApp::OnInit(){
printf("init");
}
extern "C" void foo(){
printf("foo\n");
}
thanks
AH, your OnInit() os within the shared object XD I knew there was a missing puzzle piece somewhere.
Unfortunately I never did this, so I cannot readily answer. Maybe someone else can? You might also want to consider making wxWidgets part of the main application, not only the shared object; this might be easier
Unfortunately I never did this, so I cannot readily answer. Maybe someone else can? You might also want to consider making wxWidgets part of the main application, not only the shared object; this might be easier
I have tried with and without widgets on both files. It seems to be something that is platform especific that widgets didn't port or something like that. Because I simply couldn't find a way to automatically enter OnInit.
If so, there is no need to declare a wxApp if it is a library, since you can't use the wxApp functions. Has anyone built library under linux and found out how to use it?
thanks
If so, there is no need to declare a wxApp if it is a library, since you can't use the wxApp functions. Has anyone built library under linux and found out how to use it?
thanks