digitalmars.D.learn - Help: running a method from the importing file's method "space"
- Rowan (56/56) Apr 30 2012 Hi all,
- Era Scarecrow (2/20) Apr 30 2012 Add 'import test;' to your MyLib module.
- Era Scarecrow (7/8) Apr 30 2012 Although that seems like it's connecting a library to something
- Rowan (41/49) Apr 30 2012 I make this library to create a few classes for creating some
- Rowan (3/3) Apr 30 2012 With MyLib obviously containing the MyLibInit(HINSTANCE hInst,
- Rowan (2/3) Apr 30 2012 That does work, but I didn't want to change the source of MyLib,
- Era Scarecrow (4/7) Apr 30 2012 Is there a reason the library needs to call outside of it's own
- Regan Heath (61/61) May 01 2012 I'm not sure if any of this is helpful but I've had a tinker and had som...
- Rowan (15/89) May 01 2012 Thank you very much for the input, I tried to do what you said
Hi all, Two things first: 1) I am quite new to D and have been using Java at school and a bit of C++ at home so some things confuse me. Please bear with me. 2) Apologies about the ambiguity of the title, I have no idea how to ask this in just one line so I'll elaborate here: What I want to do is create a static library to create a small wrapper/ to the Win API GUI functions for some basic GUI components for some projects instead of using some of the already made and slightly bulky GUI libraries around for D. This is what gives me a problem explained below. I need the WinMain(...) entry point to be run so that I can get my window handle for many of the windows GUI functions so using main() is out, and I want WinMain to be in the library, so the entry point of the program is in the library not the importing file, so if I have my (simplified) files: -------------- File: MyLib.d: -------------- module MyLib; import core.runtime; import core.sys.windows.windows; //import std.string; extern(windows) { int WinMain(...) { int success; //Init code success = myWin(...); return success; } } int myWin(...) { progMain(); } //Other code... -------------- File: test.d (i.e. importing file): -------------- import MyLib; pragma(lib, "MyLib.lib"); void progMain() { //User TODO code... } So if I want to make any file (in this case "test.d", which can just import MyLib after I have -lib'd it and use the custom "entry point" -> "progMain" after "MyLib" has gotten everything it needs from the WinMain entry point, so that the programmer (me) can now just import MyLib and start typing their code in progMain instead of the usual main() without having to alter the source of MyLib. Basically I want MyLib to be able to call test's "progMain()", as when I try I get some error along the lines of progMain() not existing. I hope someone understands me, if you do and have an answer could you give me a step by step way of doing this? Thanks -Rowan
Apr 30 2012
On Monday, 30 April 2012 at 18:30:29 UTC, Rowan wrote:-------------- File: MyLib.d: -------------- module MyLib; import core.runtime; import core.sys.windows.windows; //import std.string; So if I want to make any file (in this case "test.d", which can just import MyLib after I have -lib'd it and use the custom "entry point" -> "progMain" after "MyLib" has gotten everything it needs from the WinMain entry point, so that the programmer (me) can now just import MyLib and start typing their code in progMain instead of the usual main() without having to alter the source of MyLib. Basically I want MyLib to be able to call test's "progMain()", as when I try I get some error along the lines of progMain() not existing. I hope someone understands me, if you do and have an answer could you give me a step by step way of doing this?Add 'import test;' to your MyLib module.
Apr 30 2012
On Monday, 30 April 2012 at 18:50:24 UTC, Era Scarecrow wrote:Add 'import test;' to your MyLib module.Although that seems like it's connecting a library to something it shouldn't... In which case perhaps a delegate passed to the library to call myProg? Doesn't seem right either. What is your library suppose to do? And why should it have to access something outside it's library set? (Unless test.d is part of the library)
Apr 30 2012
On Monday, 30 April 2012 at 18:54:41 UTC, Era Scarecrow wrote:On Monday, 30 April 2012 at 18:50:24 UTC, Era Scarecrow wrote:I make this library to create a few classes for creating some simple GUI components (window, buttons, text boxes, that's about it) as a bit of a learning exercise, and for practical use. "test.d" is not part of the library, it is just for testing the library. What I could do that would definatly work is: -------------- File "test.d": -------------- import core.runtime; import core.sys.windows.windows; import MyLib; pragma(lib, "MyLib.lib); extern(Windows) { WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR CmdLine, int CmdShow) { MyLibInit(hInst, hPrevInst, CmdLine, CmdShow); } ----ENDFILE---- So I can then just pass everything my lib requires to it and then there is no need for progMain. I'm asking this question as with QT's source, it uses WinMain: https://qt.gitorious.org/qt/qt/blobs/HEAD/src/winmain/qtmain_win.cpp 80 /* 81 WinMain() - Initializes Windows and calls user's startup function main(). 82 NOTE: WinMain() won't be called if the application was linked as a "console" 83 application. 84 */ 85 86 #ifdef Q_OS_WINCE 87 int WINAPI WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPWSTR /*wCmdParam*/, int cmdShow) Yet you can still use "main()" from your program and then link to QT's dll and use its functionality. I know that is C++ but that's where I'm comming from with this. I think you are right and my library isn't supposed to try access "test.d"'s methods, classes, etc. and be self contained. So should I rather go with the WinMain in my main program then pass the parameters to MyLib like I showed before the QT reference?Add 'import test;' to your MyLib module.Although that seems like it's connecting a library to something it shouldn't... In which case perhaps a delegate passed to the library to call myProg? Doesn't seem right either. What is your library suppose to do? And why should it have to access something outside it's library set? (Unless test.d is part of the library)
Apr 30 2012
With MyLib obviously containing the MyLibInit(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR CmdLine, int CmdShow) method.
Apr 30 2012
Add 'import test;' to your MyLib module.That does work, but I didn't want to change the source of MyLib, I dunno maybe what I'm asking isn't possible.
Apr 30 2012
On Monday, 30 April 2012 at 19:22:35 UTC, Rowan wrote:Is there a reason the library needs to call outside of it's own library access? When I think of a library it's suppose to be self contained. Perhaps just the approach is wrong?Add 'import test;' to your MyLib module.That does work, but I didn't want to change the source of MyLib, I dunno maybe what I'm asking isn't possible.
Apr 30 2012
I'm not sure if any of this is helpful but I've had a tinker and had some measure of success :p I think you have the following issues to resolve: 1. When you build the lib, you need to tell it that the progMain symbol is to be found 'extern'ally. 2. When you build the exe, you have to make sure the linker goes looking for WinMain and not main /and/ that it looks in the lib for it. I've managed to get something "working" but it's not what you want (but it might help you get there) and it's not pretty... 1. Add the following line to mylib.d: extern(C) int progMain(); This tells dmd that when it compiles mylib.d the symbol progMain is to be found externally, and it's C linkage (I tried D linkage, but this prepends "MyLib" to the symbol it searches for). 2. Modify test.d and make it read: extern(C) void progMain() { This makes progMain a C linkage symbol, which the linker will find and use. 3. Compile mylib.d with: dmd -c mylib (I know, this doesn't build a lib more on that later..) 4. Compile test.d with: dmd -c test 5. Run link.exe manually, e.g. <path to dmd bin>\link.exe test+mylib,,nul,phobos+user32+kernel32/noi; This produces a test.exe which runs and executes progMain from test.d. Initially I was trying to get it working with a lib but I got dead-ended. Using the code changes I mentioned above, and a test.def which reads: EXETYPE NT SUBSYSTEM WINDOWS If you go: dmd -lib mylib dmd -c test link.exe test,,nul,mylib+phobos+user32+kernel32/noi,test.def; you get: OPTLINK : Warning 134: No Start Address I think that the reason for this is that test.obj does not define an entry point, see: http://www.digitalmars.com/ctg/OptlinkErrorMessages.html (No Start Address) This implies it is looking for entry points in object files, and perhaps that means /not/ libs?? Not sure. So, I tried to re-use my earlier extern trick adding: extern(Windows) int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow); to test.d, but that gave the same results. References.. http://dlang.org/windows.html http://www.digitalmars.com/ctg/optlink.html https://github.com/AndrejMitrovic/DWinProgramming -- Using Opera's revolutionary email client: http://www.opera.com/mail/
May 01 2012
On Tuesday, 1 May 2012 at 17:34:23 UTC, Regan Heath wrote:I'm not sure if any of this is helpful but I've had a tinker and had some measure of success :p I think you have the following issues to resolve: 1. When you build the lib, you need to tell it that the progMain symbol is to be found 'extern'ally. 2. When you build the exe, you have to make sure the linker goes looking for WinMain and not main /and/ that it looks in the lib for it. I've managed to get something "working" but it's not what you want (but it might help you get there) and it's not pretty... 1. Add the following line to mylib.d: extern(C) int progMain(); This tells dmd that when it compiles mylib.d the symbol progMain is to be found externally, and it's C linkage (I tried D linkage, but this prepends "MyLib" to the symbol it searches for). 2. Modify test.d and make it read: extern(C) void progMain() { This makes progMain a C linkage symbol, which the linker will find and use. 3. Compile mylib.d with: dmd -c mylib (I know, this doesn't build a lib more on that later..) 4. Compile test.d with: dmd -c test 5. Run link.exe manually, e.g. <path to dmd bin>\link.exe test+mylib,,nul,phobos+user32+kernel32/noi; This produces a test.exe which runs and executes progMain from test.d. Initially I was trying to get it working with a lib but I got dead-ended. Using the code changes I mentioned above, and a test.def which reads: EXETYPE NT SUBSYSTEM WINDOWS If you go: dmd -lib mylib dmd -c test link.exe test,,nul,mylib+phobos+user32+kernel32/noi,test.def; you get: OPTLINK : Warning 134: No Start Address I think that the reason for this is that test.obj does not define an entry point, see: http://www.digitalmars.com/ctg/OptlinkErrorMessages.html (No Start Address) This implies it is looking for entry points in object files, and perhaps that means /not/ libs?? Not sure. So, I tried to re-use my earlier extern trick adding: extern(Windows) int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow); to test.d, but that gave the same results. References.. http://dlang.org/windows.html http://www.digitalmars.com/ctg/optlink.html https://github.com/AndrejMitrovic/DWinProgrammingThank you very much for the input, I tried to do what you said and followed your instructions and went through link.exe and did get a successful compile. What you have done does work (tested it by omitting the .def file in link to get the console window and did a writeln in WinMain for mylib AND progMain for test and it does work (both wrileln's from WinMain and progMain print to console) :-). This is pretty much what I wanted, yet it is still, as you put it "not pretty", and making a lib for it isn't working. It's a bit late here, so I'll tinker around tomorrow or the day after with this and see if I can get towards more of a cleaner way of doing this, I'll post back here with what I find. Once again thank you, this seems like a nudge in the right direction. -Rowan
May 01 2012