1. RE: wxWindows DLLs
- Posted by Matthew Lewis <matthewwalkerlewis at YAHOO.COM> Feb 04, 2003
- 490 views
> From: David Cuny [mailto:dcuny at LANSET.COM] > A short time back someone posted something about wrapping > wxWindows in a DLL. > I've been looking for an example of how to do this for some time. > > If I could get an example of how this could be done, I'd > appreciate it. I think it was me. I simply compiled wxWindows with MSVC, using the project/workspace files that came with the source. I haven't tried it, but I think that there's a Borland makefile for making a dll. In any case, I use Dependency Walker to get a listing of all the exports--undecorated--and I've been importing them by ordinal, and calling by pointer. I haven't touched this stuff for a couple of weeks, but here's about where I am. I've been able to create a window, but unable to get the main message loop to work. I've been getting error messages from event.c (line 699, IIRC), but haven't figured out where they're really coming from, since I've been doing a lot of the work on a box w/out MSVC, so I've been without a debugger. I've probably declared something wrong somewhere, and its a really stupid bug, but it's going to be a real pain to figure out. The debug version of the dll is about 4.8Mb (takes about a half hour to compile on a P/MMX 200), though it UPXs down to about 1.5Mb, and then zips to a little over 1Mb. There are between 11,000 and 12,000 exports. Here's what I've done in Eu to try to make it work: Set up an OnInit for class MyApp. Set up a wxCreateApp function that allocates memory and calls the wxApp constructor, then pokes the address for MyApp::OnInit into the vtbl. Call wxAppInitializer (it's exported in the dll) with a pointer to wxCreateApp. Then I call wxEntry. I've been trying to translate the Fractal demo that comes with the source, so MyApp::OnInit calls code that creates a Frame. And then it breaks... Matt Lewis
2. RE: wxWindows DLLs
- Posted by Matthew Lewis <matthewwalkerlewis at YAHOO.COM> Feb 05, 2003
- 485 views
> From: David Cuny [mailto:dcuny at LANSET.COM] > The include makefile apparently builds a DLL, but it's > apparently for the > libraries that wxWindows uses, as opposed to the wxWindows > functions. I could > be wrong about this. Hmmm. I'll have to try it... > > In any case, I use Dependency Walker to get a listing of all the > > exports--undecorated--and I've been importing them by ordinal, and > > calling by pointer. > > If you've got a trivial example you could send me, I'd appreciate it. It's actually pretty simple. GetProcAddr will take either a pointer to a string, or an ordinal number (if the high word is 0, then it assumes you're asking for an ordinal). Then I have a pointer to the function (equivalent to define_c_var). I think Rob was going to allow this in 2.4. Then I can use my fptr.e lib to call the functions by pointer. > > I've been able to create a window, but unable to get the main > > message loop to work. > > A lot of initialization is hidden in the macros, so it's not > entirely clear > how things should be set up. Working with DLLs makes it doubly so. Yeah, it took a while to straighten some of that stuff out. > > The debug version of the dll is about 4.8Mb (takes about a > half hour to > > compile on a P/MMX 200), though it UPXs down to about > 1.5Mb, and then zips > > to a little over 1Mb. There are between 11,000 and 12,000 exports. > > That sounds about right. > > > > Here's what I've done in Eu to try to make it work: > > In my code, all callbacks are handled by the same routine. > The identity of the > callback is stored in the m_callbackUserData of the event: <snip> > Pretty trivial. All events are handled by the same routine, > defined in wxApp. I hadn't gotten that far yet. I'd just made explicit routines for the events. > All that's left is to connect a handler to an event. That's > also pretty > trivial: > > handler->Connect( id, > (wxEventType) theEvent, > (wxObjectEventFunction) (wxEventFunction) > &wxBasic::HandleEvent, > new wCallback( routine ) ); Yeah, I'm using Connect, as well. > I was thinking the way that it should work is there be a routine like > set_callback() in the DLL that you could pass a pointer to, > and it would set > up the pointer back to Euphoria (or whatever language was > calling). Getting > the DLL to call back was something I never quite figured out > - the syntax to > pointers to functions gives me a headache. Well, it calls myApp_Create() and myApp_OnInit() alright. > > Set up an OnInit for class MyApp. > > Set up a wxCreateApp function that allocates memory and > calls the wxApp > > constructor, then pokes the address for MyApp::OnInit into the vtbl. > > Call wxAppInitializer (it's exported in the dll) with a pointer to > > wxCreateApp. > > Then I call wxEntry. > > I'm not clear why you have to poke the address of > MyApp::OnInit into the > vtable. DLL magic? No, C++ magic. :) Since I'm coding in Euphoria, I have to do some of the housekeeping that C++ automatically does when you derive a class and override a virtual function. The 'this' pointer points to where the object stores everything about itself. The first 4 bytes contain the pointer to the object's vtable. That's the only way to call a function's virtual functions (OK, OK, they're actually exported by the DLL, so you can get pointers to them that way). So when I create an object, I allocate memory and call its parent's constructor. Then I change the addresses of the virtual functions I've overloaded. > I use: > > IMPLEMENT_APP(wxBasic) > > to setup the app, but for DLLs you have to do something else. > There's an > IMPLEMENT_APP_NO_MAIN macro that looks promising, but I can't > find any > documentation for it. After straightening out all the imbedded macros, I think I'm doing everything that gets done by IMPEMENT_APP(). My gut feeling is that I have a memory allocation problem, or I'm storing something incorrectly. Matt Lewis