Re: Undefined function, even though imported

2011-06-14 Thread Loopback

Well, I solved the linker error by specifying imports in the
.def file. The pathetic thing was that the def file was invalid
just because I had a newline, or at least it worked without it.

So my final .def file looks like this:

EXETYPE NT
SUBSYSTEM WINDOWS
IMPORTS
_Direct3DCreate9@4 = d3d9.Direct3DCreate9

Thanks for all help!


Re: Undefined function, even though imported

2011-06-14 Thread Loopback

On 2011-06-14 18:30, Trass3r wrote:

Am 14.06.2011, 02:43 Uhr, schrieb Loopback :


Thanks for all the answers! Seems like rdmd did the trick.
I don't see why this isn't built in to dmd though


No one does ;)


Haha well it would be nice if at least one soul knew and could explain..

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


So the other functions in d3d9 work but only this one doesn't?



Yeah, that's why I think this i related to D somehow and not the
binding itself. Though I'm just guessing.

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


^^ This can't work cause the linker knows nothing about D modules.
You'd have to use the correct D mangled name.

I see your point, but I think the IMPORTS statement refers to the lib
file, and the lib file is still C (since D can import c libs).

But I still haven't got it to work yet, so I would really appreciate
if someone knows what I am doing wrong with the def file/pragma
statements!


Re: Undefined function, even though imported

2011-06-14 Thread Trass3r

Am 14.06.2011, 02:43 Uhr, schrieb Loopback :


Thanks for all the answers! Seems like rdmd did the trick.
I don't see why this isn't built in to dmd though


No one does ;)


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


So the other functions in d3d9 work but only this one doesn't?



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


^^ This can't work cause the linker knows nothing about D modules.
You'd have to use the correct D mangled name.


Re: Undefined function, even though imported

2011-06-13 Thread bearophile
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

2011-06-13 Thread Loopback

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: Undefined function, even though imported

2011-06-13 Thread Trass3r

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

2011-06-13 Thread Andrej Mitrovic
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

2011-06-13 Thread Loopback

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?


Re: Undefined function, even though imported

2011-06-13 Thread Jonathan M Davis
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

2011-06-13 Thread Loopback

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

2011-06-13 Thread Jonathan M Davis
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: Undefined function, even though imported

2011-06-13 Thread Trass3r
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

2011-06-13 Thread Mafi

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

2011-06-13 Thread 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
/***\
*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
}