Dinamic loading Static linking on linux

Do you have a typical platform dependent issue you're battling with ? Ask it here. Make sure you mention your platform, compiler, and wxWidgets version.
Post Reply
rodrigod
I live to help wx-kind
I live to help wx-kind
Posts: 172
Joined: Thu Jun 26, 2008 8:50 pm

Dinamic loading Static linking on linux

Post by rodrigod »

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
Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Post by Auria »

build a library that is loaded dynamically but linked statically.
Sorry, if this exists at all, I never heard about it.
rodrigod
I live to help wx-kind
I live to help wx-kind
Posts: 172
Joined: Thu Jun 26, 2008 8:50 pm

Post by rodrigod »

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?
rodrigod
I live to help wx-kind
I live to help wx-kind
Posts: 172
Joined: Thu Jun 26, 2008 8:50 pm

Post by rodrigod »

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
Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Post by Auria »

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)
But now there is the problem is that it doesnt enter the OnInit function when the library is loaded.
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.
rodrigod
I live to help wx-kind
I live to help wx-kind
Posts: 172
Joined: Thu Jun 26, 2008 8:50 pm

Post by rodrigod »

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

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
header

Code: Select all

 class CACTIONRESApp : public wxApp

 {
	 bool OnInit();

 };
That part that is windows only shouldnt matter now but I put it just to show it was working on windows.
Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Post by Auria »

Well i think it does matter. You call wxEntry in a part #ifdef'ed to be called only on Windows. So on linux wxEntry() will never be called...
rodrigod
I live to help wx-kind
I live to help wx-kind
Posts: 172
Joined: Thu Jun 26, 2008 8:50 pm

Post by rodrigod »

Good eye. So any clues on how could i get the same effect on linux?
Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Post by Auria »

rodrigod wrote:Good eye. So any clues on how could i get the same effect on linux?
just use a plain main() instead of the DLL-main?
rodrigod
I live to help wx-kind
I live to help wx-kind
Posts: 172
Joined: Thu Jun 26, 2008 8:50 pm

Post by rodrigod »

I added this main and it never entered

Code: Select all

int main(int argc, char **argv){
	 wxMessageBox("main");
	 wxEntry(argc,argv);
	 
 }
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
Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Post by Auria »

I'm not an expert with IMPLEMENT_APP_NO_MAIN, but... if all you do in main() is call wxEntry, why not use the regular macro?

Also, calling wxMessageBox() before wxEntry() might not be a good idea? I'm not sure it would work. Perhaps try using a printf() to the terminal
rodrigod
I live to help wx-kind
I live to help wx-kind
Posts: 172
Joined: Thu Jun 26, 2008 8:50 pm

Post by rodrigod »

i tried using IMPLEMENT_APP, still it doesn't go through OnInit, and neither wxMessageBox, printf and wxLogDebug worked. If I make a small project reproducing this would you mind taking look?

thanks
rodrigod
I live to help wx-kind
I live to help wx-kind
Posts: 172
Joined: Thu Jun 26, 2008 8:50 pm

Post by rodrigod »

I am trying with something very simple to see if I can make it go through OnInit.
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;
}
this would be the code for the linked shared object

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");
}
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
Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Post by Auria »

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
rodrigod
I live to help wx-kind
I live to help wx-kind
Posts: 172
Joined: Thu Jun 26, 2008 8:50 pm

Post by rodrigod »

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
Post Reply