Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
April 30, 2012 Help: running a method from the importing file's method "space" | ||||
---|---|---|---|---|
| ||||
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 |
April 30, 2012 Re: Help: running a method from the importing file's method "space" | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rowan | 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.
|
April 30, 2012 Re: Help: running a method from the importing file's method "space" | ||||
---|---|---|---|---|
| ||||
Posted in reply to Era Scarecrow | 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)
|
April 30, 2012 Re: Help: running a method from the importing file's method "space" | ||||
---|---|---|---|---|
| ||||
Posted in reply to Era Scarecrow | > 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.
|
April 30, 2012 Re: Help: running a method from the importing file's method "space" | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rowan | On Monday, 30 April 2012 at 19:22:35 UTC, Rowan wrote:
>> 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.
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?
|
April 30, 2012 Re: Help: running a method from the importing file's method "space" | ||||
---|---|---|---|---|
| ||||
Posted in reply to Era Scarecrow | 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: >> 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) 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? |
April 30, 2012 Re: Help: running a method from the importing file's method "space" | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rowan | With MyLib obviously containing the MyLibInit(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR CmdLine, int CmdShow) method. |
May 01, 2012 Re: Help: running a method from the importing file's method "space" | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rowan | 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 Re: Help: running a method from the importing file's method "space" | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | 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/DWinProgramming
Thank 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
|
Copyright © 1999-2021 by the D Language Foundation