Re: WindowsAPI Binding - Linker Errors
On 6/13/2011 9:00 PM, Loopback wrote: Hello! I've been test programming win32 applications recently, and since the phobos win32 library is so limited, I decided to download and test the WindowsAPI Binding (http://www.dsource.org/projects/bindings/wiki/WindowsApi). Using the latest snapshot (as of this writing) I receive the following linker errors when I compile: Error 42: Symbol Undefined _D5win328winerror12MAKE_HRESULTFbkkZi (MAKE_HRESULT is undefined). These are my imports: win32.mmsystem, win32.windef, win32.winuser, win32.wingdi and win32.directx.d3d9. The problem lies within the DirectX module. If I do not import it, there are no errors. I've taken the d3d9.lib and d3dx9.lib from the DirectX SDK and used coffimplib and the linked to them, without success. These are the libraries I am linking to: gdi32.lib, winmm.lib and d3d9.lib. Any theories why MAKE_HRESULT is undefined? Have I forgotten to link to something? Linking to win32 libs won't help you here. MAKE_HRESULT is a macro on the C-side, so no symbol exists for it in any of the win32 libs. On the D side, you can find it declared as a function in the bindings in winerror.d. In d3d9.d, it is called from the function MAKE_D3DHRESULT. So you need to make sure that winerror.d is compiled and linked into your executable.
Should I bother porting Win32 threading examples?
I'm in the process of porting WinAPI examples from Petzold's Windows Programming book to D. In the book there's a chapter on multithreading. It covers thread creation, messaging queues, critical sections, TLS (heh..), and event signaling. Since we pretty much have all of this in D already (+ its multiplatform), I'm thinking it might be a good idea to skip translating this chapter's samples. I don't want to encourage newbies to use WinAPI threading functions when it's completely unnecessary to do so. I *could* however demonstrate how it's done in D instead, and put some documentation in the modules on how it works. So while it won't follow what the book says, at least it's there instead of being completely left out. Whaddya think, Windoze users?
Re: Is it reasonable to learn D
On Mon, Jun 13, 2011 at 6:33 AM, Lloyd Dupont wrote: > Let's learn together then! :P > http://galador.net/codeblog/?tag=/D > > While my blog post are only about setting up the environment so far.. I have > delved in the code for 2 weeks now! (Although I had some day off (work and > programing) in Darwin) I'm right into it now, should have a new blog post > soon! About programing this time! > > My verdict: it's frustrating yes. But D has a couple of advantages and 2 > that you might like: > - D has event / delegate, just like C# (and unlike C++, or maybe C++ has > them, (it has method pointer, right!?) but it's not taken advantage of!) > - the above point is probably what makes the C++ GUI so... difficult. > Whereas I found a GUI API for D just like WinForm! (DGui!) > Boost, GTK+ and QT have signals. E.g. http://www.boost.org/doc/libs/1_46_1/doc/html/signals.html
Re: Is there any convenient CopyMemory function in Phobos?
On 2011-06-13 17:38, Andrej Mitrovic wrote: > So why's it in core.stdc.string, instead of say.. core.memory? > > Btw, I've had some imports already in the module and it seems these > two conflict: > > import core.thread; > import core.stdc.string; > > void main() > { > int* p, x; > memcpy(p, x, 1); > } > > test.d(9): Error: core.stdc.string.memcpy at > D:\DMD\dmd2\windows\bin\..\..\src\druntime\import\core\stdc\string.di(11) > conflicts with core.thread.memcpy at > D:\DMD\dmd2\windows\bin\..\..\src\druntime\import\core\thread.di(37) core.thread has its own private declaration of memcpy (IIRC, they don't match for some reason). Why a private declaration conflicts, I don't know. That certainly _sounds_ like a bug. Regardless, I have no clue why those declarations are where they are. I would have expected something like core.memory, but they seem to be strewn about druntime. That should probably be improved. I just grepped druntime to find where memcpy's declaration was. I don't know why it is where it is. - Jonathan M Davis
Re: Is there any convenient CopyMemory function in Phobos?
Andrej Mitrovic: > Right, haven't thought about the C functions at all (silly me). > Thanks, this did the trick: > extern (C) void* memcpy(void*, const void*, size_t); Maybe you are able to wrap that memcpy in a templated D function (named copyMemory) that does what you want in a bit safer way, that contains some static and runtime asserts, etc. Bye, bearophile
Re: Undefined function, even though imported
Trass3r Wrote: > > Shouldn't the linker/compiler be able to solve this on its own then? > > Use rdmd or xfBuild to automatically compile all needed modules. Everyone we'll keep asking that question forever until the D compiler does this by itself :-) Bye, bearophile
Re: Undefined function, even though imported
Thanks for all the answers! Seems like rdmd did the trick. I don't see why this isn't built in to dmd though, or does it cause overhead when you are using rdmd? Benefits, Drawbacks? I've also stumbled upon an additional error with the win32 DirectX bindings, but this seems D related actually. When I compile any code at all (with rdmd) which imports win32.directx.d3d9 and uses the function Direct3DCreate9, the linker issues this warning: Error 42: Symbol Undefined _Direct3DCreate9@4 It is shown even though I'm using rdmd and I have linked to d3d9.lib (other functions like CreateDevice and Present still works though). To solve this error, I did some searching and it seems like I'm not the first one with this problem. I got 2 hits: http://www.digitalmars.com/d/archives/digitalmars/D/learn/1475.html http://www.dsource.org/forums/viewtopic.php?p=13971&sid=d43d05620f0c3a30758a326394ac2e26 Both of these links says that the problem is solved by adding _Direct3DCreate9 to imports. I've tried to do this by linking to a .def file with this content (without success, same error is still issued). EXETYPE NT SUBSYSTEM WINDOWS IMPORTS _Direct3DCreate9@4=d3d9.Direct3DCreate9 I also tried this code but pragma build_def seems deprecated: pragma(build_def, "IMPORTS"); pragma(build_def, "_Direct3DCreate9@4=d3d9.Direct3DCreate9"); So am I doing something wrong with the def file or am I perhaps supposed to use another pragma? Thanks in advance!
Re: Is there any convenient CopyMemory function in Phobos?
So why's it in core.stdc.string, instead of say.. core.memory? Btw, I've had some imports already in the module and it seems these two conflict: import core.thread; import core.stdc.string; void main() { int* p, x; memcpy(p, x, 1); } test.d(9): Error: core.stdc.string.memcpy at D:\DMD\dmd2\windows\bin\..\..\src\druntime\import\core\stdc\string.di(11) conflicts with core.thread.memcpy at D:\DMD\dmd2\windows\bin\..\..\src\druntime\import\core\thread.di(37)
Re: Is there any convenient CopyMemory function in Phobos?
On 2011-06-13 17:01, Andrej Mitrovic wrote: > Right, haven't thought about the C functions at all (silly me). > Thanks, this did the trick: > extern (C) void* memcpy(void*, const void*, size_t); core.stdc.string has memcpy's declaration in it. You should be able to just import it rather than declaring memcpy yourself. - Jonathan M Davis
Re: Is there any convenient CopyMemory function in Phobos?
Right, haven't thought about the C functions at all (silly me). Thanks, this did the trick: extern (C) void* memcpy(void*, const void*, size_t);
Re: Is there any convenient CopyMemory function in Phobos?
On 2011-06-13 16:27, Andrej Mitrovic wrote: > Apparently in the Windows API there's a whole lot of byte-copying going > around. > > Here's an example: > > int CALLBACK EnhMetaFileProc (HDC hdc, HANDLETABLE * pHandleTable, > CONST ENHMETARECORD * pEmfRecord, > int iHandles, LPARAM pData) > { > ENHMETARECORD * pEmfr ; > > pEmfr = (ENHMETARECORD *) malloc (pEmfRecord->nSize) ; > > CopyMemory (pEmfr, pEmfRecord, pEmfRecord->nSize) ; > > if (pEmfr->iType == EMR_RECTANGLE) > pEmfr->iType = EMR_ELLIPSE ; > > PlayEnhMetaFileRecord (hdc, pHandleTable, pEmfr, iHandles) ; > > free (pEmfr) ; > > return TRUE ; > } > > The nSize field specifies the byte size of the structure pointed to by > pEmfRecord. The reason copying is required is because of this code: > if (pEmfr->iType == EMR_RECTANGLE) > pEmfr->iType = EMR_ELLIPSE ; > > pEmfRecord itself is const, so new memory has to be allocated first > and then the memory from pEmfRecord is copied there, and then the > iType field is changed. A simple pointer dereference won't copy all > the bytes, since this is one of those variable-length structure types > you often see in C code. > > In D I've used the slice trick to assign a byte range of data from one > memory location to another: > extern (Windows) > int EnhMetaFileProc(HDC hdc, HANDLETABLE* pHandleTable, > const ENHMETARECORD* pEmfRecord, > int iHandles, LPARAM pData) > { > ENHMETARECORD* pEmfr; > immutable newlength = pEmfRecord.nSize; > > pEmfr = cast(ENHMETARECORD*)GC.malloc(newlength); > > (cast(ubyte*)pEmfr)[0..newlength] = > (cast(ubyte*)pEmfRecord)[0..newlength]; > > if (pEmfr.iType == EMR_RECTANGLE) > pEmfr.iType = EMR_ELLIPSE; > > PlayEnhMetaFileRecord(hdc, pHandleTable, pEmfr, iHandles); > > GC.free(pEmfr); > return TRUE; > } > > That's quite ugly.. Is there a Phobos/Druntime and maybe > platform-independent function that can do byte-memory copies in a > simple way? Something like this is what I need: > CopyBytes(dest, src, bytecount); > > Btw, CopyMemory is a WinAPI specific function, but I can't even link > to it (it's actually an alias to RtlCopyMemory, but it's not in > kernel32.lib for some reason even though MSDN says it is). mempcy? The C memory functions are all available in D. - Jonathan M Davis
Is there any convenient CopyMemory function in Phobos?
Apparently in the Windows API there's a whole lot of byte-copying going around. Here's an example: int CALLBACK EnhMetaFileProc (HDC hdc, HANDLETABLE * pHandleTable, CONST ENHMETARECORD * pEmfRecord, int iHandles, LPARAM pData) { ENHMETARECORD * pEmfr ; pEmfr = (ENHMETARECORD *) malloc (pEmfRecord->nSize) ; CopyMemory (pEmfr, pEmfRecord, pEmfRecord->nSize) ; if (pEmfr->iType == EMR_RECTANGLE) pEmfr->iType = EMR_ELLIPSE ; PlayEnhMetaFileRecord (hdc, pHandleTable, pEmfr, iHandles) ; free (pEmfr) ; return TRUE ; } The nSize field specifies the byte size of the structure pointed to by pEmfRecord. The reason copying is required is because of this code: if (pEmfr->iType == EMR_RECTANGLE) pEmfr->iType = EMR_ELLIPSE ; pEmfRecord itself is const, so new memory has to be allocated first and then the memory from pEmfRecord is copied there, and then the iType field is changed. A simple pointer dereference won't copy all the bytes, since this is one of those variable-length structure types you often see in C code. In D I've used the slice trick to assign a byte range of data from one memory location to another: extern (Windows) int EnhMetaFileProc(HDC hdc, HANDLETABLE* pHandleTable, const ENHMETARECORD* pEmfRecord, int iHandles, LPARAM pData) { ENHMETARECORD* pEmfr; immutable newlength = pEmfRecord.nSize; pEmfr = cast(ENHMETARECORD*)GC.malloc(newlength); (cast(ubyte*)pEmfr)[0..newlength] = (cast(ubyte*)pEmfRecord)[0..newlength]; if (pEmfr.iType == EMR_RECTANGLE) pEmfr.iType = EMR_ELLIPSE; PlayEnhMetaFileRecord(hdc, pHandleTable, pEmfr, iHandles); GC.free(pEmfr); return TRUE; } That's quite ugly.. Is there a Phobos/Druntime and maybe platform-independent function that can do byte-memory copies in a simple way? Something like this is what I need: CopyBytes(dest, src, bytecount); Btw, CopyMemory is a WinAPI specific function, but I can't even link to it (it's actually an alias to RtlCopyMemory, but it's not in kernel32.lib for some reason even though MSDN says it is).
Re: So how exactly does one make a persistent range object?
On Sat, 04 Jun 2011 20:27:16 +0200, Andrej Mitrovic wrote: > This is my #1 problem with ranges right now: > > import std.range; > > int[3] a = [1, 2, 3]; > shared range = cycle(a[]); // nope > > void main() > { > foo(); > } > > void foo() > { > // do something with range > } > > test.d(6): Error: static variable a cannot be read at compile time > test.d(6): Error: cannot evaluate cycle(a[]) at compile time Has this been answered? The problem is with 'a'. Defining it as enum fixes that problem: import std.stdio; import std.range; enum a = [1, 2, 3]; auto range = cycle(a[]); void main() { foreach (i; 0 .. 2) { foo(); } } void foo() { foreach(i; 0 .. 5) { writeln(range.front); range.popFront(); } } Ali
Re: Undefined function, even though imported
Shouldn't the linker/compiler be able to solve this on its own then? Use rdmd or xfBuild to automatically compile all needed modules.
Re: Undefined function, even though imported
sc.ini is going to get overwritten when you upgrade DMD so changing it is a bad idea. An alternative is to copy sc.ini to your projects local directory, this way DMD will use that one instead of its own. But this is all working around the issue that you should be passing import directories via a build script, makefile, or some type of build system (that's a bit difficult given the current state of build tools..), and not hardcoding paths to a global config file. Btw, there are some notes on how to use DMD/Optlink and static libs here: http://prowiki.org/wiki4d/wiki.cgi?D__Tutorial/CompilingLinkingD I can't tell if it's any good until someone bothers to try things out and see if things work like the page describes. If something's wrong or that page doesn't explain what you need to know, let me know and I'll try to update it with more information.
Re: Undefined function, even though imported
On 2011-06-13 23:51, Jonathan M Davis wrote: On 2011-06-13 14:44, Loopback wrote: Thanks for your answer! Seems like supplying with the file location solved the problem, though I still wonder about one thing. The imported module is located in "c:/d/dmd2/import/win32/windef.d" and I have used this command line to the DMD compiler: -I"c:/d/dmd2/import/". Shouldn't the linker/compiler be able to solve this on its own then? -I just tells it where to look for imports, not what to link. The linker never links in anything unless you explicitly tell it to - either by having it directly on the command line or in DFLAGS (usually set by dmd.conf on Linux and sc.ini or Windows). Phobos is listed in dmd.conf/sc.ini, which is why it gets linked in. If it wasn't there, you'd have to list it explicitly too. - Jonathan M Davis Can you modify the sc.ini so the linker automatically checks a specific directory for imports? Let's say for example this I have my imports in c:/d/dmd2/import/, can I implement this in sc.ini so I don't have to worry about these specific linker errors again? I tried adding "-I%@P%\..\..\import" (custom import directory) in sc.ini without success. Another question I'm wondering is; if I include a module and tell its location explicitly to the linker, do I then also have to tell the linker the location of all local imports this file have as well?
Running DMD tests
I'm trying to run the test suite for DMD, but I'm running into issues. I've cloned dmd from github, and successfully built dmd, but when I run 'make' from the dmd/test dir, I get: $ make Creating output directory: test_results Building d_do_test tool object.d: Error: module object is in file 'object.d' which cannot be read Specify path to file 'object.d' with -I switch make: *** [test_results/d_do_test] Error 1 Do I need to set up my environment differently to run dmd in development? How can I get around this? Note: I'm running OSX 10.6.7 Thanks
Re: Undefined function, even though imported
On 2011-06-13 14:44, Loopback wrote: > Thanks for your answer! > > Seems like supplying with the file location solved the problem, though I > still wonder about one thing. The imported module is located in > "c:/d/dmd2/import/win32/windef.d" and I have used this command line to > the DMD compiler: -I"c:/d/dmd2/import/". Shouldn't the linker/compiler > be able to solve this on its own then? -I just tells it where to look for imports, not what to link. The linker never links in anything unless you explicitly tell it to - either by having it directly on the command line or in DFLAGS (usually set by dmd.conf on Linux and sc.ini or Windows). Phobos is listed in dmd.conf/sc.ini, which is why it gets linked in. If it wasn't there, you'd have to list it explicitly too. - Jonathan M Davis
Re: Undefined function, even though imported
Thanks for your answer! Seems like supplying with the file location solved the problem, though I still wonder about one thing. The imported module is located in "c:/d/dmd2/import/win32/windef.d" and I have used this command line to the DMD compiler: -I"c:/d/dmd2/import/". Shouldn't the linker/compiler be able to solve this on its own then?
Re: Undefined function, even though imported
On 2011-06-13 14:18, Loopback wrote: > Hi! > > Let me begin by saying, I'm sorry if this is caused of some obvious > error but since I am new to D, I am not aware of all the tricks and > treats it offers. > > I am working with the WindowsAPI binding at dsource.org (though I do not > believe this is related to the binding itself). However, in my code I > call the function LOWORD (win32 specific). This function is defined in > the win32.windef module. Although it is defined there (without any > encapsulations in version statements or anything similar) I receive this > error: > > Error 42: Symbol Undefined _D5win326windef6LOWORDFkZt (LOWORD undefined) > > To solve this I had to copy-paste the exact function directly into my > own file/module instead. So my question is the following; why do I have > to copy and paste the function directly in my code when it is clearly > defined in one of the files I import? > > Windef.d attached Importing the module with the function in it means that the compilation of the current module can see that module and use its symbols. But the compiled functions in the imported module are in the object file generated when compiling that module, not the current module. In the case of binding to a C function, you're telling D that a function with that signature exists, but it doesn't have the source to it. In either case, the actual function definition is going to be needed when linking (at least with static linking - it's a bit more complicated with dynamic linking, but on Windows at least, the .lib file still needs to be linked in). In this particular case, one of two things is likely happening. 1. You never linked in the lib file for the library with the function. 2. The declaration given for the C function in question isn't using the right linking. That is, it needs to be extern(C) and/or extern(Windows) (I'm not quite sure what extern(Windows) does differently than extern(C), but I gather that it's necessary at least some of the time when dealing with Windows system functions). The symbol that it's complaining about looks rather mangled to me (though I don't look at pure C function symbols very often, so I don't know exactly what they look like unmangled - both C++ and D mangle functions to allow for function overloading). So, it's likely that the function's declaration in D isn't properly marked with extern(C) or extern(Windows). So, the function's name gets mangled, and it can't find the unmangled C function in the .lib file. Regardless, that particular error indicates that the linker failed to locate that particular function, and you have to make whatever changes are necessary - either in code or in your compilation process - to make it so that the linker is able to find the definition of the function in question. - Jonathan M Davis
Re: Clear big AAs
useo: > toRender is my AA which contains the textures as key (instances of my > class "Texture") and the tiles (position of them) as values. When I > remove the first two lines (clear and set null) it doesn't drops down > to 1 FPS, it runs normal. > > I hope anyone know a solution :) Try to disable the GC before that double loop and enable after it. Generally those appends create lot of garbage, so it's not something to do in a performance critical part of the program (try to use fixed-sized arrays, or structs with a fixed-sized array plus a length). You can also try an AA of appender. Also try to profile your code, and take a look at GC stats. Bye, bearophile
Re: Undefined function, even though imported
Importing it means dmd knows about the function and emits a call but doesn't automatically generate the function code. This is only done if you also pass the file containing it to dmd.
Re: Undefined function, even though imported
Am 13.06.2011 23:18, schrieb Loopback: Hi! Let me begin by saying, I'm sorry if this is caused of some obvious error but since I am new to D, I am not aware of all the tricks and treats it offers. I am working with the WindowsAPI binding at dsource.org (though I do not believe this is related to the binding itself). However, in my code I call the function LOWORD (win32 specific). This function is defined in the win32.windef module. Although it is defined there (without any encapsulations in version statements or anything similar) I receive this error: Error 42: Symbol Undefined _D5win326windef6LOWORDFkZt (LOWORD undefined) To solve this I had to copy-paste the exact function directly into my own file/module instead. So my question is the following; why do I have to copy and paste the function directly in my code when it is clearly defined in one of the files I import? Windef.d attached Your error is an linker error. This means the last step of creating an exceutable couldn't be taken: finding all names you promised to be there. When you, import a module, you promise: "Compiler, I know that definitions I'm using in this module aren't declared in there, but look at this module. I promise that all these functions in there will be there during the linking process". The compiler gives no error because you promised, but now the linker has problem: It hasn't got the defintions you said to be there. You have to say the linker where to find them. One way is to give your .d/.lib file to dmd so he can give it to the linker: dmd main.d path/to/windef.d Mafi
Undefined function, even though imported
Hi! Let me begin by saying, I'm sorry if this is caused of some obvious error but since I am new to D, I am not aware of all the tricks and treats it offers. I am working with the WindowsAPI binding at dsource.org (though I do not believe this is related to the binding itself). However, in my code I call the function LOWORD (win32 specific). This function is defined in the win32.windef module. Although it is defined there (without any encapsulations in version statements or anything similar) I receive this error: Error 42: Symbol Undefined _D5win326windef6LOWORDFkZt (LOWORD undefined) To solve this I had to copy-paste the exact function directly into my own file/module instead. So my question is the following; why do I have to copy and paste the function directly in my code when it is clearly defined in one of the files I import? Windef.d attached /***\ *windef.d * * * * Windows API header module * * * * Translated from MinGW Windows headers * * by Stewart Gordon * * * * Placed into public domain * \***/ module win32.windef; public import win32.winnt; private import win32.w32api; const size_t MAX_PATH = 260; ushort MAKEWORD(ubyte a, ubyte b) { return cast(ushort) ((b << 8) | a); } uint MAKELONG(ushort a, ushort b) { return cast(uint) ((b << 16) | a); } ushort LOWORD(uint l) { return cast(ushort) l; } ushort HIWORD(uint l) { return cast(ushort) (l >>> 16); } ubyte LOBYTE(ushort w) { return cast(ubyte) w; } ubyte HIBYTE(ushort w) { return cast(ubyte) (w >>> 8); } template max(T) { T max(T a, T b) { return a > b ? a : b; } } template min(T) { T min(T a, T b) { return a < b ? a : b; } } const void* NULL = null; alias ubyte BYTE; alias ubyte* PBYTE, LPBYTE; alias ushort USHORT, WORD, ATOM; alias ushort* PUSHORT, PWORD, LPWORD; alias uintULONG, DWORD, UINT, COLORREF; alias uint* PULONG, PDWORD, LPDWORD, PUINT, LPUINT; alias int WINBOOL, BOOL, INT, LONG, HFILE, HRESULT; alias int*PWINBOOL, LPWINBOOL, PBOOL, LPBOOL, PINT, LPINT, LPLONG; alias float FLOAT; alias float* PFLOAT; alias CPtr!(void) PCVOID, LPCVOID; alias UINT_PTR WPARAM; alias LONG_PTR LPARAM, LRESULT; alias HANDLE HGLOBAL, HLOCAL, GLOBALHANDLE, LOCALHANDLE, HGDIOBJ, HACCEL, HBITMAP, HBRUSH, HCOLORSPACE, HDC, HGLRC, HDESK, HENHMETAFILE, HFONT, HICON, HINSTANCE, HKEY, HMENU, HMETAFILE, HMODULE, HMONITOR, HPALETTE, HPEN, HRGN, HRSRC, HSTR, HTASK, HWND, HWINSTA, HKL, HCURSOR; alias HANDLE* PHKEY; static if (WINVER >= 0x500) { alias HANDLE HTERMINAL, HWINEVENTHOOK; } alias extern (Windows) int function() FARPROC, NEARPROC, PROC; struct RECT { LONG left; LONG top; LONG right; LONG bottom; } alias RECT RECTL; alias RECT* PRECT, LPRECT, PRECTL, LPRECTL; alias CPtr!(RECT) LPCRECT, LPCRECTL; struct POINT { LONG x; LONG y; } alias POINT POINTL; alias POINT* PPOINT, LPPOINT, PPOINTL, LPPOINTL; struct SIZE { LONG cx; LONG cy; } alias SIZE SIZEL; alias SIZE* PSIZE, LPSIZE, PSIZEL, LPSIZEL; struct POINTS { SHORT x; SHORT y; } alias POINTS* PPOINTS, LPPOINTS; enum : BOOL { FALSE = 0, TRUE = 1 }
Re: WindowsAPI Binding - Linker Errors
"Nick Sabalausky" wrote in message news:it5ui1$1l75$1...@digitalmars.com... > "Loopback" wrote in message > news:it4ud4$1kf5$1...@digitalmars.com... >> Hello! >> >> I've been test programming win32 applications recently, and since the >> phobos win32 library is so limited, I decided to download and test the >> WindowsAPI Binding >> (http://www.dsource.org/projects/bindings/wiki/WindowsApi). Using the >> latest snapshot (as of this writing) I receive the following linker >> errors when I compile: >> >> Error 42: Symbol Undefined _D5win328winerror12MAKE_HRESULTFbkkZi >> (MAKE_HRESULT is undefined). >> >> These are my imports: win32.mmsystem, win32.windef, win32.winuser, >> win32.wingdi and win32.directx.d3d9. >> >> The problem lies within the DirectX module. If I do not import it, there >> are no errors. I've taken the d3d9.lib and d3dx9.lib from the DirectX SDK >> and used coffimplib and the linked to them, without success. >> >> These are the libraries I am linking to: gdi32.lib, winmm.lib and >> d3d9.lib. >> >> Any theories why MAKE_HRESULT is undefined? Have I forgotten to link to >> something? > > You could maybe try Derelict: http://www.dsource.org/projects/derelict > Sorry, I thought Derelict did DirectX. Looking at it now, I guess maybe it doesn't.
Re: WindowsAPI Binding - Linker Errors
"Loopback" wrote in message news:it4ud4$1kf5$1...@digitalmars.com... > Hello! > > I've been test programming win32 applications recently, and since the > phobos win32 library is so limited, I decided to download and test the > WindowsAPI Binding > (http://www.dsource.org/projects/bindings/wiki/WindowsApi). Using the > latest snapshot (as of this writing) I receive the following linker errors > when I compile: > > Error 42: Symbol Undefined _D5win328winerror12MAKE_HRESULTFbkkZi > (MAKE_HRESULT is undefined). > > These are my imports: win32.mmsystem, win32.windef, win32.winuser, > win32.wingdi and win32.directx.d3d9. > > The problem lies within the DirectX module. If I do not import it, there > are no errors. I've taken the d3d9.lib and d3dx9.lib from the DirectX SDK > and used coffimplib and the linked to them, without success. > > These are the libraries I am linking to: gdi32.lib, winmm.lib and > d3d9.lib. > > Any theories why MAKE_HRESULT is undefined? Have I forgotten to link to > something? You could maybe try Derelict: http://www.dsource.org/projects/derelict
Re: Int within ranges
== Auszug aus Steven Schveighoffer (schvei...@yahoo.com)'s Artikel > On Mon, 13 Jun 2011 15:44:01 -0400, nrgyzer wrote: > >> On Mon, 13 Jun 2011 14:52:24 -0400, nrgyzer > > wrote: > >> >> On Mon, 13 Jun 2011 12:15:40 -0400, nrgyzer > >> > wrote: > >> >> > Hi there, > >> >> > > >> >> > is there any possibility to get a sliced array from another > > array > >> >> > between two ranges like: > >> >> > > >> >> > int[uint] myArray; > >> >> > myArray[10] = 1000; > >> >> > myArray[20] = 2000; > >> >> > myArray[30] = 3000; > >> >> > myArray[40] = 4000; > >> >> > myArray[50] = 5000; > >> >> > > >> >> > int[] newArray = myArray[>= 20 .. <= 40]; // not able to do > > this > >> >> > writeln(newArray); // should print [2000, 3000, 4000] > >> >> > > >> >> > Is there any way to do this? > >> >> import dcollections.TreeMap; > >> >> auto myArray = new TreeMap!(uint, int); > >> >> myArray[10] = 1000; > >> >> myArray[20] = 2000; > >> >> myArray[30] = 3000; > >> >> myArray[40] = 4000; > >> >> myArray[50] = 5000; > >> >> // this is a little kludgy, but necessary since you require <= 40 > >> >> auto c = myArray.elemAt(40); > >> >> c.popFront(); > >> >> int newArray = array(myArray[20..c]); > >> >> Note two things: > >> >> 1. int[uint] is a hash, and so has no particular order. > > Therefore, > >> > there > >> >> is no guarantee of iteration order, or that a range of such a > >> > container > >> >> (if one existed) would be properly constructed with two keys. A > >> > TreeMap, > >> >> or RedBlackTree, is sorted, and so the order is guaranteed. > >> >> 2. dcollections.TreeMap is implemented with the same collection > > as > >> >> std.container.RedBlackTree, so you could potentially do the same > >> > thing > >> >> with it. But the dcollections.TreeMap API is more polished. > >> >> -Steve > >> > > >> > Exactly what I'm looking for, but how can I realize that it also > >> > gives me the elements when the key doesn't exists like: > >> > > >> > import std.range; > >> > import dcollections.TreeMap; > >> > > >> > auto myArray = new TreeMap!(uint, int); > >> > > >> > myArray[10] = 1000; > >> > myArray[20] = 2000; > >> > myArray[30] = 3000; > >> > myArray[45] = 4500; > >> > myArray[50] = 5000; > >> > > >> > auto c = myArray.elemAt(40); > >> > c.popFront(); > >> > int[] newArray = array(myArray[20..c]); > >> > writeln(newArray); > >> > > >> > This will throw an exception because element 40 doesn't exist. Is > >> > there any possibility to get the element 20 and 30 from this map? > >> It might be useful to have elemAt return an empty range that is > > located at > >> the place the element *would* be. > >> When this code was first written, in order to detect whether elemAt > > found > >> your element, you compared it to container.end (similar to C++'s > > STL). > >> But now that cursors are tiny ranges, and have an empty property, I > > can > >> use that to indicate the element wasn't exactly found. So I can > > change > >> the semantics to find the place the element *would* be. > >> myArray[20..41]; > >> and it will find all elements >= 20 and < 41, regardless of whether > > 20 and > >> 41 were valid elements. > >> Hm... can you post this as an enhancement to dcollections so it's > > not > >> forgotten? > >> http://www.dsource.org/projects/dcollections/newticket > >> -Steve > > > > Thanks! I created a new ticket... by the way - is there any bug in > > DMD 2.053 by using my own opCmp? The following code throws me an > > HiddenFuncException: > > > > private import std.stdio : writeln; > > > > class Example { > > > > int pId; > > > > this(int id) { > > > > pId = id; > > > > } > > > > int opCmp(ref Example other) { > The signature of this function must be > int opCmp(Object other) > Note, also, that ref is unnecessary, as all objects (i.e. class instances) > are passed by reference. > -Steve Works, thanks for all that!
Re: Int within ranges
On Mon, 13 Jun 2011 15:44:01 -0400, nrgyzer wrote: On Mon, 13 Jun 2011 14:52:24 -0400, nrgyzer wrote: >> On Mon, 13 Jun 2011 12:15:40 -0400, nrgyzer > wrote: >> > Hi there, >> > >> > is there any possibility to get a sliced array from another array >> > between two ranges like: >> > >> > int[uint] myArray; >> > myArray[10] = 1000; >> > myArray[20] = 2000; >> > myArray[30] = 3000; >> > myArray[40] = 4000; >> > myArray[50] = 5000; >> > >> > int[] newArray = myArray[>= 20 .. <= 40]; // not able to do this >> > writeln(newArray); // should print [2000, 3000, 4000] >> > >> > Is there any way to do this? >> import dcollections.TreeMap; >> auto myArray = new TreeMap!(uint, int); >> myArray[10] = 1000; >> myArray[20] = 2000; >> myArray[30] = 3000; >> myArray[40] = 4000; >> myArray[50] = 5000; >> // this is a little kludgy, but necessary since you require <= 40 >> auto c = myArray.elemAt(40); >> c.popFront(); >> int newArray = array(myArray[20..c]); >> Note two things: >> 1. int[uint] is a hash, and so has no particular order. Therefore, > there >> is no guarantee of iteration order, or that a range of such a > container >> (if one existed) would be properly constructed with two keys. A > TreeMap, >> or RedBlackTree, is sorted, and so the order is guaranteed. >> 2. dcollections.TreeMap is implemented with the same collection as >> std.container.RedBlackTree, so you could potentially do the same > thing >> with it. But the dcollections.TreeMap API is more polished. >> -Steve > > Exactly what I'm looking for, but how can I realize that it also > gives me the elements when the key doesn't exists like: > > import std.range; > import dcollections.TreeMap; > > auto myArray = new TreeMap!(uint, int); > > myArray[10] = 1000; > myArray[20] = 2000; > myArray[30] = 3000; > myArray[45] = 4500; > myArray[50] = 5000; > > auto c = myArray.elemAt(40); > c.popFront(); > int[] newArray = array(myArray[20..c]); > writeln(newArray); > > This will throw an exception because element 40 doesn't exist. Is > there any possibility to get the element 20 and 30 from this map? It might be useful to have elemAt return an empty range that is located at the place the element *would* be. When this code was first written, in order to detect whether elemAt found your element, you compared it to container.end (similar to C++'s STL). But now that cursors are tiny ranges, and have an empty property, I can use that to indicate the element wasn't exactly found. So I can change the semantics to find the place the element *would* be. myArray[20..41]; and it will find all elements >= 20 and < 41, regardless of whether 20 and 41 were valid elements. Hm... can you post this as an enhancement to dcollections so it's not forgotten? http://www.dsource.org/projects/dcollections/newticket -Steve Thanks! I created a new ticket... by the way - is there any bug in DMD 2.053 by using my own opCmp? The following code throws me an HiddenFuncException: private import std.stdio : writeln; class Example { int pId; this(int id) { pId = id; } int opCmp(ref Example other) { The signature of this function must be int opCmp(Object other) Note, also, that ref is unnecessary, as all objects (i.e. class instances) are passed by reference. -Steve
Re: Int within ranges
> On Mon, 13 Jun 2011 14:52:24 -0400, nrgyzer wrote: > >> On Mon, 13 Jun 2011 12:15:40 -0400, nrgyzer > > wrote: > >> > Hi there, > >> > > >> > is there any possibility to get a sliced array from another array > >> > between two ranges like: > >> > > >> > int[uint] myArray; > >> > myArray[10] = 1000; > >> > myArray[20] = 2000; > >> > myArray[30] = 3000; > >> > myArray[40] = 4000; > >> > myArray[50] = 5000; > >> > > >> > int[] newArray = myArray[>= 20 .. <= 40]; // not able to do this > >> > writeln(newArray); // should print [2000, 3000, 4000] > >> > > >> > Is there any way to do this? > >> import dcollections.TreeMap; > >> auto myArray = new TreeMap!(uint, int); > >> myArray[10] = 1000; > >> myArray[20] = 2000; > >> myArray[30] = 3000; > >> myArray[40] = 4000; > >> myArray[50] = 5000; > >> // this is a little kludgy, but necessary since you require <= 40 > >> auto c = myArray.elemAt(40); > >> c.popFront(); > >> int newArray = array(myArray[20..c]); > >> Note two things: > >> 1. int[uint] is a hash, and so has no particular order. Therefore, > > there > >> is no guarantee of iteration order, or that a range of such a > > container > >> (if one existed) would be properly constructed with two keys. A > > TreeMap, > >> or RedBlackTree, is sorted, and so the order is guaranteed. > >> 2. dcollections.TreeMap is implemented with the same collection as > >> std.container.RedBlackTree, so you could potentially do the same > > thing > >> with it. But the dcollections.TreeMap API is more polished. > >> -Steve > > > > Exactly what I'm looking for, but how can I realize that it also > > gives me the elements when the key doesn't exists like: > > > > import std.range; > > import dcollections.TreeMap; > > > > auto myArray = new TreeMap!(uint, int); > > > > myArray[10] = 1000; > > myArray[20] = 2000; > > myArray[30] = 3000; > > myArray[45] = 4500; > > myArray[50] = 5000; > > > > auto c = myArray.elemAt(40); > > c.popFront(); > > int[] newArray = array(myArray[20..c]); > > writeln(newArray); > > > > This will throw an exception because element 40 doesn't exist. Is > > there any possibility to get the element 20 and 30 from this map? > It might be useful to have elemAt return an empty range that is located at > the place the element *would* be. > When this code was first written, in order to detect whether elemAt found > your element, you compared it to container.end (similar to C++'s STL). > But now that cursors are tiny ranges, and have an empty property, I can > use that to indicate the element wasn't exactly found. So I can change > the semantics to find the place the element *would* be. > myArray[20..41]; > and it will find all elements >= 20 and < 41, regardless of whether 20 and > 41 were valid elements. > Hm... can you post this as an enhancement to dcollections so it's not > forgotten? > http://www.dsource.org/projects/dcollections/newticket > -Steve Thanks! I created a new ticket... by the way - is there any bug in DMD 2.053 by using my own opCmp? The following code throws me an HiddenFuncException: private import std.stdio : writeln; class Example { int pId; this(int id) { pId = id; } int opCmp(ref Example other) { return pId - other.pId; } } int main(string[] args) { Example[] exps; exps ~= new Example(1); exps ~= new Example(2); writeln(exps.sort); return 1; }
Re: Int within ranges
On Mon, 13 Jun 2011 14:52:24 -0400, nrgyzer wrote: On Mon, 13 Jun 2011 12:15:40 -0400, nrgyzer wrote: > Hi there, > > is there any possibility to get a sliced array from another array > between two ranges like: > > int[uint] myArray; > myArray[10] = 1000; > myArray[20] = 2000; > myArray[30] = 3000; > myArray[40] = 4000; > myArray[50] = 5000; > > int[] newArray = myArray[>= 20 .. <= 40]; // not able to do this > writeln(newArray); // should print [2000, 3000, 4000] > > Is there any way to do this? import dcollections.TreeMap; auto myArray = new TreeMap!(uint, int); myArray[10] = 1000; myArray[20] = 2000; myArray[30] = 3000; myArray[40] = 4000; myArray[50] = 5000; // this is a little kludgy, but necessary since you require <= 40 auto c = myArray.elemAt(40); c.popFront(); int newArray = array(myArray[20..c]); Note two things: 1. int[uint] is a hash, and so has no particular order. Therefore, there is no guarantee of iteration order, or that a range of such a container (if one existed) would be properly constructed with two keys. A TreeMap, or RedBlackTree, is sorted, and so the order is guaranteed. 2. dcollections.TreeMap is implemented with the same collection as std.container.RedBlackTree, so you could potentially do the same thing with it. But the dcollections.TreeMap API is more polished. -Steve Exactly what I'm looking for, but how can I realize that it also gives me the elements when the key doesn't exists like: import std.range; import dcollections.TreeMap; auto myArray = new TreeMap!(uint, int); myArray[10] = 1000; myArray[20] = 2000; myArray[30] = 3000; myArray[45] = 4500; myArray[50] = 5000; auto c = myArray.elemAt(40); c.popFront(); int[] newArray = array(myArray[20..c]); writeln(newArray); This will throw an exception because element 40 doesn't exist. Is there any possibility to get the element 20 and 30 from this map? It might be useful to have elemAt return an empty range that is located at the place the element *would* be. When this code was first written, in order to detect whether elemAt found your element, you compared it to container.end (similar to C++'s STL). But now that cursors are tiny ranges, and have an empty property, I can use that to indicate the element wasn't exactly found. So I can change the semantics to find the place the element *would* be. myArray[20..41]; and it will find all elements >= 20 and < 41, regardless of whether 20 and 41 were valid elements. Hm... can you post this as an enhancement to dcollections so it's not forgotten? http://www.dsource.org/projects/dcollections/newticket -Steve
Re: Int within ranges
> On Mon, 13 Jun 2011 12:15:40 -0400, nrgyzer wrote: > > Hi there, > > > > is there any possibility to get a sliced array from another array > > between two ranges like: > > > > int[uint] myArray; > > myArray[10] = 1000; > > myArray[20] = 2000; > > myArray[30] = 3000; > > myArray[40] = 4000; > > myArray[50] = 5000; > > > > int[] newArray = myArray[>= 20 .. <= 40]; // not able to do this > > writeln(newArray); // should print [2000, 3000, 4000] > > > > Is there any way to do this? > import dcollections.TreeMap; > auto myArray = new TreeMap!(uint, int); > myArray[10] = 1000; > myArray[20] = 2000; > myArray[30] = 3000; > myArray[40] = 4000; > myArray[50] = 5000; > // this is a little kludgy, but necessary since you require <= 40 > auto c = myArray.elemAt(40); > c.popFront(); > int newArray = array(myArray[20..c]); > Note two things: > 1. int[uint] is a hash, and so has no particular order. Therefore, there > is no guarantee of iteration order, or that a range of such a container > (if one existed) would be properly constructed with two keys. A TreeMap, > or RedBlackTree, is sorted, and so the order is guaranteed. > 2. dcollections.TreeMap is implemented with the same collection as > std.container.RedBlackTree, so you could potentially do the same thing > with it. But the dcollections.TreeMap API is more polished. > -Steve Exactly what I'm looking for, but how can I realize that it also gives me the elements when the key doesn't exists like: import std.range; import dcollections.TreeMap; auto myArray = new TreeMap!(uint, int); myArray[10] = 1000; myArray[20] = 2000; myArray[30] = 3000; myArray[45] = 4500; myArray[50] = 5000; auto c = myArray.elemAt(40); c.popFront(); int[] newArray = array(myArray[20..c]); writeln(newArray); This will throw an exception because element 40 doesn't exist. Is there any possibility to get the element 20 and 30 from this map?
Re: Int within ranges
On 2011-06-13 09:15, nrgyzer wrote: > Hi there, > > is there any possibility to get a sliced array from another array > between two ranges like: > > int[uint] myArray; > myArray[10] = 1000; > myArray[20] = 2000; > myArray[30] = 3000; > myArray[40] = 4000; > myArray[50] = 5000; > > int[] newArray = myArray[>= 20 .. <= 40]; // not able to do this > writeln(newArray); // should print [2000, 3000, 4000] > > Is there any way to do this? Slices take a contiguous chunk of an array. You can't skip any values. So, if you want them separate, you're going to have to put them in another container yourself. - Jonathan M Davis
Re: Int within ranges
On Mon, 13 Jun 2011 13:25:39 -0400, bearophile < wrote: Steven Schveighoffer: But the dcollections.TreeMap API is more polished. I think most people will want to use just Phobos, to avoid a dependency, even if the Phobos one is less polished... Sure, but it's difficult to demonstrate a possible solution without having the API for slicing present in the phobos version... Essentially, what I'm saying is it *could* be done in Phobos, if phobos' RedBlackTree was updated to be like dcollections'. -Steve
Re: Int within ranges
Steven Schveighoffer: > But the dcollections.TreeMap API is more polished. I think most people will want to use just Phobos, to avoid a dependency, even if the Phobos one is less polished... Bye, bearophile
Re: Int within ranges
On Mon, 13 Jun 2011 12:15:40 -0400, nrgyzer wrote: Hi there, is there any possibility to get a sliced array from another array between two ranges like: int[uint] myArray; myArray[10] = 1000; myArray[20] = 2000; myArray[30] = 3000; myArray[40] = 4000; myArray[50] = 5000; int[] newArray = myArray[>= 20 .. <= 40]; // not able to do this writeln(newArray); // should print [2000, 3000, 4000] Is there any way to do this? import dcollections.TreeMap; auto myArray = new TreeMap!(uint, int); myArray[10] = 1000; myArray[20] = 2000; myArray[30] = 3000; myArray[40] = 4000; myArray[50] = 5000; // this is a little kludgy, but necessary since you require <= 40 auto c = myArray.elemAt(40); c.popFront(); int newArray = array(myArray[20..c]); Note two things: 1. int[uint] is a hash, and so has no particular order. Therefore, there is no guarantee of iteration order, or that a range of such a container (if one existed) would be properly constructed with two keys. A TreeMap, or RedBlackTree, is sorted, and so the order is guaranteed. 2. dcollections.TreeMap is implemented with the same collection as std.container.RedBlackTree, so you could potentially do the same thing with it. But the dcollections.TreeMap API is more polished. -Steve
Int within ranges
Hi there, is there any possibility to get a sliced array from another array between two ranges like: int[uint] myArray; myArray[10] = 1000; myArray[20] = 2000; myArray[30] = 3000; myArray[40] = 4000; myArray[50] = 5000; int[] newArray = myArray[>= 20 .. <= 40]; // not able to do this writeln(newArray); // should print [2000, 3000, 4000] Is there any way to do this?
Re: simple syntax issue with template
> I'm trying to create 2 extra method for arrays ("range" would be > better, though I don't quite understand what is a "range") > Although I have some indecipherable (to me) compiler error... > > What's wrong with the code below? > == > import std.algorithm; > > public: > > void remove(T)(ref T[] array, T element) > { >auto index = array.countUntil!("a == b", T[], T)(array, element); >removeAt(index); > } > > void removeAt(T)(ref T[] array, sizediff_t index) > { >if(index < 0 || index >= array.length) >return; >array.replaceInPlace(index, index + 1, []); > } > > > unittest > { >auto a = [1, 3, 4]; >a.remove(3); >assert(a == [1, 4]); > } > == Hi Lloyd, why not just use the built in functionality of arrays? //-- import std.stdio; void main() { auto a = [1, 2, 3, 4, 5, 6, 7, 8]; remove(a, 3); foreach (i; a) { write(i, " "); } writeln(""); } void remove(T) (ref T[] myarray, int element) { auto front = myarray[0 .. (element -1)]; auto back = myarray[element .. $]; myarray = front ~ back; // or simply: myarray = myarray[0 .. (element - 1)] ~ myarray[element .. $]; } //-- Josh
Re: simple syntax issue with template
On 13.06.2011 16:49, Lloyd Dupont wrote: ho.. plenty of silly mistake indeed.. thanks for spotting them! (maybe I should take a break and play the witcher 2 hey!?!? :) Why not ? ;-) however I still have a problem with removeAt now! :( === void removeAt(T)(ref T[] array, int index) { if(index < 0 || index >= array.length) return; array.replaceInPlace(index, index + 1, []); } Yeah, I think I've hit this issue before, and used plain cast(T[])[]. The problem is that [] is null of type void[], and template fails to resolve type. Seems like insertInPlace probably should take this special case into account. === will produce the following errors: === Error: template std.array.replaceInPlace(T,Range) if (isDynamicArray!(Range) && is(ElementEncodingType!(Range) : T) && !is(T == const(T)) && !is(T == immutable(T))) does not match any function template declaration Error: template std.array.replaceInPlace(T,Range) if (isDynamicArray!(Range) && is(ElementEncodingType!(Range) : T) && !is(T == const(T)) && !is(T == immutable(T))) cannot deduce template function from argument types !()(int[],int,int,void[]) === mmm.. strangely enough the code below succeed! void removeAt(T)(ref T[] array, int index) { if(index < 0 || index >= array.length) return; T[] empty; array.replaceInPlace(index, index + 1, empty); } but T[].init didn't work either?! ho well, thanks! :) -- Dmitry Olshansky
Re: dmd vs rdmd
Thanks Jonathan, that cleared things up for me. Josh On Sat, Jun 11, 2011 at 12:00 PM, wrote: > Send Digitalmars-d-learn mailing list submissions to >digitalmars-d-learn@puremagic.com > > To subscribe or unsubscribe via the World Wide Web, visit > > http://lists.puremagic.com/cgi-bin/mailman/listinfo/digitalmars-d-learn > > or, via email, send a message with subject or body 'help' to >digitalmars-d-learn-requ...@puremagic.com > > You can reach the person managing the list at >digitalmars-d-learn-ow...@puremagic.com > > When replying, please edit your Subject line so it is more specific > than "Re: Contents of Digitalmars-d-learn digest..." > > > Today's Topics: > > 1. dmd vs rdmd (Joshua Niehus) > 2. Re: dmd vs rdmd (Jonathan M Davis) > 3. Re: dmd vs rdmd (Andrej Mitrovic) > 4. char[] to string (Jonathan Sternberg) > 5. Re: char[] to string (Jonathan M Davis) > 6. Re: DMD Backend: Deciding instructions to use/avoid? > (Nick Sabalausky) > 7. Re: char[] to string (bearophile) > > > -- > > Message: 1 > Date: Fri, 10 Jun 2011 14:28:41 -0700 > From: Joshua Niehus > To: digitalmars-d-learn@puremagic.com > Subject: dmd vs rdmd > Message-ID: > Content-Type: text/plain; charset="iso-8859-1" > > Hello, > > I am trying to compile code which is composed of two modules (in the same > directory): > > main.d > foo.d > > foo.d just declares a class Foo which has a string variable "bar" which i > set to "hello" and main.d just prints bar's value to the console: > > // - main.d --- > import std.stdio, foo; > > void main() { >Foo f = new Foo; >writeln(f.bar); > } > > When i attempt to compile main.d via: > $dmd main.d > I get undefined symbol errors. > > But when I run: > $rdmd main.d > it works as expected. > > The only way I could get main.d to compile with just dmd was to compile foo > as a lib first and then compile main.d and passing the foo.a file as an > argument: > $dmd -lib foo.d > $dmd main.d foo.a > > Is this normal? > I got the impression from TDPL (Alexandrescu) that the dmd compiler would > automatically search the root directory, find foo.d, work its magic, and > create all the symbols that were defined in foo.d for main.d to compile... > > Thanks, > Josh > -- next part -- > An HTML attachment was scrubbed... > URL: < > http://lists.puremagic.com/pipermail/digitalmars-d-learn/attachments/20110610/dccf485f/attachment-0001.html > > > > -- > > Message: 2 > Date: Fri, 10 Jun 2011 21:50:37 + > From: "Jonathan M Davis" > To: "digitalmars.D.learn" > Subject: Re: dmd vs rdmd > Message-ID: <20110610215037.56...@gmx.com> > Content-Type: text/plain; charset="utf-8" > > On 2011-06-10 14:28, Joshua Niehus wrote: > > Hello, > > > > I am trying to compile code which is composed of two modules (in the same > > directory): > > > > main.d > > foo.d > > > > foo.d just declares a class Foo which has a string variable "bar" which i > > set to "hello" and main.d just prints bar's value to the console: > > > > // - main.d --- > > import std.stdio, foo; > > > > void main() { > > Foo f = new Foo; > > writeln(f.bar); > > } > > > > When i attempt to compile main.d via: > > $dmd main.d > > I get undefined symbol errors. > > > > But when I run: > > $rdmd main.d > > it works as expected. > > > > The only way I could get main.d to compile with just dmd was to compile > foo > > as a lib first and then compile main.d and passing the foo.a file as an > > argument: > > $dmd -lib foo.d > > $dmd main.d foo.a > > > > Is this normal? > > I got the impression from TDPL (Alexandrescu) that the dmd compiler would > > automatically search the root directory, find foo.d, work its magic, and > > create all the symbols that were defined in foo.d for main.d to > compile... > > With dmd, you must list every file that you're compiling. The only > exceptions > are that when dealing with libraries, dmd to have the root directory where > the > source is passed to -I, and it needs to have the root directory where the > library is given with -L and -l with the library name (or just the library > directly if you don't want it to search for the library). It's like gcc and > dmc in that respect. It does nothing extra to track down files to compile > for > you. It'll find the source for importing thanks to -I, but it won't compile > it. You must still compile it. You don't normally need -I or -L however, > because dmd.conf (or sc.ini on Windows) already adds the appropriate flags > for > Phobos for you. You only need too specify them yourself when using other > libraries. > > rdmd does extra magic to automatically track down all of the files that > main.d > imports and compile them. dmd doesn't do that. > > - Jonathan M Davis > > > -- > > Message: 3 > Date: Sat, 11 Jun 2011 01:08:50 +0200 > From: Andrej Mitrovic > To: "digitalm
Re: introspection woes (2)
Works a treat! Thanks for your detailed sample! :) "Robert Clipsham" wrote in message news:it5395$2028$1...@digitalmars.com... See: http://www.digitalmars.com/d/2.0/traits.html class MyClass { void method1(){} void method2(){} } import std.stdio; void main() { foreach (member; __traits(allMembers, MyClass)) writefln("member: %s", member); foreach (member; __traits(derivedMembers, MyClass)) writefln("derived member: %s", member); } Instead of writefln() you can append to an array. You can also make this a bit more generic with: class MyClass { mixin memberArray!MyClass; void method1(){} void method2(){} } import std.stdio; mixin template memberArray(T) { immutable static members = [__traits(derivedMembers, T)]; } void main() { foreach (member; MyClass.members) writefln("member: %s", member); } Hope this helps :) -- Robert http://octarineparrot.com/
Re: introspection woes (2)
On 13/06/2011 13:56, Lloyd Dupont wrote: Thanks Robert! Mm.. can you (per chance!) share some code? I'm a newbie and compile time reflection is something which eludes me (so far...)! See: http://www.digitalmars.com/d/2.0/traits.html class MyClass { void method1(){} void method2(){} } import std.stdio; void main() { foreach (member; __traits(allMembers, MyClass)) writefln("member: %s", member); foreach (member; __traits(derivedMembers, MyClass)) writefln("derived member: %s", member); } Instead of writefln() you can append to an array. You can also make this a bit more generic with: class MyClass { mixin memberArray!MyClass; void method1(){} void method2(){} } import std.stdio; mixin template memberArray(T) { immutable static members = [__traits(derivedMembers, T)]; } void main() { foreach (member; MyClass.members) writefln("member: %s", member); } Hope this helps :) -- Robert http://octarineparrot.com/
Re: introspection woes (2)
Thanks Robert! Mm.. can you (per chance!) share some code? I'm a newbie and compile time reflection is something which eludes me (so far...)! "Robert Clipsham" wrote in message news:it4vp1$1n5q$1...@digitalmars.com... Anyway of ... making the runtime update xgetMembers? My understanding is that xgetMembers is never filled in due to the overhead it would add. You can recompile dmd to support it, but that's a pain. The work around I use is to put a mixin in every class I want to use which uses compile time reflection to build an array which I can access at runtime. Not the most elegant solution. Perhap's a bug report needs opening for this if one isn't already open.
Re: simple syntax issue with template
ho.. plenty of silly mistake indeed.. thanks for spotting them! (maybe I should take a break and play the witcher 2 hey!?!? :) however I still have a problem with removeAt now! :( === void removeAt(T)(ref T[] array, int index) { if(index < 0 || index >= array.length) return; array.replaceInPlace(index, index + 1, []); } === will produce the following errors: === Error: template std.array.replaceInPlace(T,Range) if (isDynamicArray!(Range) && is(ElementEncodingType!(Range) : T) && !is(T == const(T)) && !is(T == immutable(T))) does not match any function template declaration Error: template std.array.replaceInPlace(T,Range) if (isDynamicArray!(Range) && is(ElementEncodingType!(Range) : T) && !is(T == const(T)) && !is(T == immutable(T))) cannot deduce template function from argument types !()(int[],int,int,void[]) === mmm.. strangely enough the code below succeed! void removeAt(T)(ref T[] array, int index) { if(index < 0 || index >= array.length) return; T[] empty; array.replaceInPlace(index, index + 1, empty); } but T[].init didn't work either?! ho well, thanks! :)
Re: introspection woes (2)
On 13/06/2011 13:11, Lloyd Dupont wrote: Interesting... I think I understand... Thanks! :) However an other problem arise with getMembers() it always returns null! Looking at the code it seems (from my beginner's perspective) that getMembers() rely on the member field (function) xgetMembers which is always null, as far as I can tell (didn't see any assignment...) Anyway of ... making the runtime update xgetMembers? My understanding is that xgetMembers is never filled in due to the overhead it would add. You can recompile dmd to support it, but that's a pain. The work around I use is to put a mixin in every class I want to use which uses compile time reflection to build an array which I can access at runtime. Not the most elegant solution. Perhap's a bug report needs opening for this if one isn't already open. -- Robert http://octarineparrot.com/
Re: simple syntax issue with template
removed some obvious error, still stumped on the templated syntax ... so.. why is it not compiling? (error: Error: template std.algorithm.countUntil(alias pred = "a == b",R1,R2) if (is(typeof(startsWith!(pred)(haystack,needle does not match any function template declaration ) = import std.algorithm; public: void remove(T)(ref T[] array, T element) { sizediff_t index = array.countUntil!("a == b", T[], T)(array, element); removeAt(array, index); } void removeAt(T)(ref T[] array, sizediff_t index) { if(index < 0 || index >= array.length) return; array.replaceInPlace(index, index + 1, []); } unittest { auto a = [1, 3, 4]; a.remove(3); assert(a == [1, 4]); } =
Re: simple syntax issue with template
On 13.06.2011 16:03, Lloyd Dupont wrote: I'm trying to create 2 extra method for arrays ("range" would be better, though I don't quite understand what is a "range") Although I have some indecipherable (to me) compiler error... What's wrong with the code below? == import std.algorithm; public: void remove(T)(ref T[] array, T element) { auto index = array.countUntil!("a == b", T[], T)(array, element); removeAt(index); } void removeAt(T)(ref T[] array, sizediff_t index) { if(index < 0 || index >= array.length) return; array.replaceInPlace(index, index + 1, []); } unittest { auto a = [1, 3, 4]; a.remove(3); assert(a == [1, 4]); } == It's not exactly clear what's your problem, since you haven't put a tiniest description of what the compiler outputs. still: array.countUntil!("a == b", T[], T)(array, element); should be ether countUntil!("a == b", T[], T)(array, element); or: array.countUntil!("a == b", T[], T)( element); also drop thouse ugly explicit template params (the compiler can and would figure them out anyway): array.countUntil!"a == b"(element); //same as default array.countUntil(element); another one: removeAt(index); should be array.removeAt(index) or removeAt(array, index); And last but not least there is remove in Phobos, it's just link to it from summary table is constantly getting screwed up. -- Dmitry Olshansky
Re: introspection woes (2)
Interesting... I think I understand... Thanks! :) However an other problem arise with getMembers() it always returns null! Looking at the code it seems (from my beginner's perspective) that getMembers() rely on the member field (function) xgetMembers which is always null, as far as I can tell (didn't see any assignment...) Anyway of ... making the runtime update xgetMembers? "Johannes Pfau" wrote in message news:20110613140030.70c8d27b@jpf-Satellite-A100... Lloyd Dupont wrote: trying to learn introspection, I have this simple test method: === static void dumpelement(Object o) { if (!o) return; auto ci = o.classinfo; foreach(mi ; ci.getMembers(null)) { writefln("%s . %s", ci.name, mi.name()); } } == Looks like getMembers() returns 'const MemberInfo' but name() is not declared as const. That's likely a bug in druntime, but as a workaround you can try this: == writefln("%s . %s", ci.name, (cast(MemberInfo)mi).name()); ==
simple syntax issue with template
I'm trying to create 2 extra method for arrays ("range" would be better, though I don't quite understand what is a "range") Although I have some indecipherable (to me) compiler error... What's wrong with the code below? == import std.algorithm; public: void remove(T)(ref T[] array, T element) { auto index = array.countUntil!("a == b", T[], T)(array, element); removeAt(index); } void removeAt(T)(ref T[] array, sizediff_t index) { if(index < 0 || index >= array.length) return; array.replaceInPlace(index, index + 1, []); } unittest { auto a = [1, 3, 4]; a.remove(3); assert(a == [1, 4]); } ==
Re: introspection woes (2)
Lloyd Dupont wrote: >trying to learn introspection, I have this simple test method: > >=== >static void dumpelement(Object o) >{ >if (!o) >return; > >auto ci = o.classinfo; >foreach(mi ; ci.getMembers(null)) >{ >writefln("%s . %s", ci.name, mi.name()); >} >} >== > >However it fails to compile with the following error: (any ideas?) >=== >main.d(57): Error: function object.MemberInfo.name () is not callable >using argument types () const >Building Debug\dtest.exe failed! > Looks like getMembers() returns 'const MemberInfo' but name() is not declared as const. That's likely a bug in druntime, but as a workaround you can try this: == writefln("%s . %s", ci.name, (cast(MemberInfo)mi).name()); == -- Johannes Pfau
WindowsAPI Binding - Linker Errors
Hello! I've been test programming win32 applications recently, and since the phobos win32 library is so limited, I decided to download and test the WindowsAPI Binding (http://www.dsource.org/projects/bindings/wiki/WindowsApi). Using the latest snapshot (as of this writing) I receive the following linker errors when I compile: Error 42: Symbol Undefined _D5win328winerror12MAKE_HRESULTFbkkZi (MAKE_HRESULT is undefined). These are my imports: win32.mmsystem, win32.windef, win32.winuser, win32.wingdi and win32.directx.d3d9. The problem lies within the DirectX module. If I do not import it, there are no errors. I've taken the d3d9.lib and d3dx9.lib from the DirectX SDK and used coffimplib and the linked to them, without success. These are the libraries I am linking to: gdi32.lib, winmm.lib and d3d9.lib. Any theories why MAKE_HRESULT is undefined? Have I forgotten to link to something?
introspection woes (2)
trying to learn introspection, I have this simple test method: === static void dumpelement(Object o) { if (!o) return; auto ci = o.classinfo; foreach(mi ; ci.getMembers(null)) { writefln("%s . %s", ci.name, mi.name()); } } == However it fails to compile with the following error: (any ideas?) === main.d(57): Error: function object.MemberInfo.name () is not callable using argument types () const Building Debug\dtest.exe failed!
Re: Is it reasonable to learn D
Let's learn together then! :P http://galador.net/codeblog/?tag=/D While my blog post are only about setting up the environment so far.. I have delved in the code for 2 weeks now! (Although I had some day off (work and programing) in Darwin) I'm right into it now, should have a new blog post soon! About programing this time! My verdict: it's frustrating yes. But D has a couple of advantages and 2 that you might like: - D has event / delegate, just like C# (and unlike C++, or maybe C++ has them, (it has method pointer, right!?) but it's not taken advantage of!) - the above point is probably what makes the C++ GUI so... difficult. Whereas I found a GUI API for D just like WinForm! (DGui!) In short summary I found these cool things: VisualD 0.3.24 (plugin for programing from Visual Studio) http://www.dsource.org/projects/visuald VisualD NOTE: (system tweaks)(required) : edit sc.ini http://www.dsource.org/projects/visuald/wiki/KnownIssues#Librarysearchpathnotpassedtolinker DGui 02052011 (WinForm like API) http://code.google.com/p/dgui/ Doost (r88) (serialization) http://www.dsource.org/projects/doost Windows API r371 http://dsource.org/projects/bindings/wiki/WindowsApi "Fabian" wrote in message news:islvgf$1b61$1...@digitalmars.com... Dear D Community, is it reasonable to learn D? I've found a lot of good points for D but I've found a lot of negative points too. I believe that I needn't to list all the point for D but I want to give a few examples against learning D I've read in some German and English boards: - The D compiler has only bad code optimization - There are no maintained GUI libraries - The development of the compiler is very slow - Only a small community => no real German community So I ask you - Is it reasonable to learn D? I'm looking forward to your answers. Greetings Fabian PS: If you want to contact me you are allowed to write an Email to me. contact-...@freemail.de
Re: Object
I see mm Thanks for the info! "Jonathan M Davis" wrote in message news:mailman.866.1307943671.14074.digitalmars-d-le...@puremagic.com... Object is not currently const-correct: http://d.puremagic.com/issues/show_bug.cgi?id=1824 As a result, a number of basic functions do not currently work with const objects. So, making opEquals const means that it's not going to work. It sucks, but until Object is fixed to be const-correct, that's the way it goes.
introspection woes...
Trying to play with introspection. trying o, for a given object, to check its property by name. Experimenting with the function below. 1. it doesn't compile! mi.name() seems to be a problem? 2. match is always null! even though I pass the name of an existing property and / or field! === Object getelement(Object o, string aname) { if (!o) return null; auto ci = o.classinfo; writefln("class: %s", ci.name); auto match = ci.getMembers(aname); foreach(mi ; ci.getMembers(null)) { writefln("%s . %s", ci.name, mi.name()); } //writefln("match: %s", match); return o; } ==