www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Problems with OpenGL bindings and D2

reply Simen Kjaeraas <simen.kjaras gmail.com> writes:
I'm using the OpenGL bindings from the Bindings project on dsource, and get a
bunch of Symbol Undefined errors, for _glViewport, _glMatrixMode, etc...
 
Now, I'm including opengl32.lib using a pragma, and have also tried doing it
from the command line. I seem to remember there being something about this no
longer working:
 
	version (Windows) {
		extern (Windows):
	} else {
		extern (C):
	}
	// functions defined here
 
So I changed that to "extern (Windows):" in gl.gl and gl.glu, and got nicer
names, which might be a good thing.
 
Any ideas to what I'm doing wrong?
 
--
Simen
Sep 16 2008
next sibling parent reply "Bill Baxter" <wbaxter gmail.com> writes:
On Wed, Sep 17, 2008 at 5:53 AM, Simen Kjaeraas <simen.kjaras gmail.com> wrote:
 I'm using the OpenGL bindings from the Bindings project on dsource, and get a
bunch of Symbol Undefined errors, for _glViewport, _glMatrixMode, etc...

 Now, I'm including opengl32.lib using a pragma, and have also tried doing it
from the command line. I seem to remember there being something about this no
longer working:

        version (Windows) {
                extern (Windows):
        } else {
                extern (C):
        }
        // functions defined here

 So I changed that to "extern (Windows):" in gl.gl and gl.glu, and got nicer
names, which might be a good thing.

 Any ideas to what I'm doing wrong?

I believe the scoping was changed so that the extern(): block no longer continued to the end of file. The fix added to make everyones programs compile again was "extern(System):" which can be used without a version block, and basically acts like "extern(Windows):" on windows and "extern(C):" everywhere else. --bb
Sep 16 2008
parent reply Sergey Gromov <snake.scaly gmail.com> writes:
Simen Kjaeraas <simen.kjaras gmail.com> wrote:
 On Wed, 17 Sep 2008 01:02:59 +0200, Bill Baxter <wbaxter gmail.com> wrote:
 
 I believe the scoping was changed so that the extern(): block  no
 longer continued to the end of file.  The fix added to make everyones
 programs compile again was "extern(System):" which can be used without
 a version block, and basically acts like "extern(Windows):" on windows
 and "extern(C):" everywhere else.

 --bb

Thanks, but that don't seem to fix my problem. However, you might be onto something, as the name mangling seems wrong. _glClear should be _glClear 4 and so on. A quick search tells me the first is __cdecl and the latter __stdcall. Moving the declarations from gl/gl.d to my source file fixed all problems. Bug?

Maybe it's the same problem I've had hit recently. The names in DLL exports are not mangled according to the calling convention rules. I.e. kernel32.dll exports CreateFileA although it's _CreateFileA 28 in Microsoft's kernel32.lib. The latter is a correctly mangled name, the former is merely a symbolic reference. There are two options for generating the correct import library, safe one, and flexible one. The safe method is available if you have a COFF (MS-compatible) import library for your DLL. Then you use http://www.digitalmars.com/ctg/coffimplib.html to convert it into an OMF import library usable with DMD. Then simply use whatever export() generates the right names for your lib. The flexible method is to use http://www.dprogramming.com/linkdef.php to create an import library based upon the linker errors produced by DMD. Beware though that it's your responsibility to choose the correct extern() calling convention. DLL does not have any calling convention meta-data, so linkdef will link any undefined symbols to the similarly named symbols in a DLL without any compatibility guarantee.
Sep 17 2008
parent Sergey Gromov <snake.scaly gmail.com> writes:
Bill Baxter <wbaxter gmail.com> wrote:
 On Wed, Sep 17, 2008 at 11:37 PM, Sergey Gromov <snake.scaly gmail.com> wrote:
 Maybe it's the same problem I've had hit recently.

 The names in DLL exports are not mangled according to the calling
 convention rules.  I.e. kernel32.dll exports CreateFileA although it's
 _CreateFileA 28 in Microsoft's kernel32.lib.  The latter is a correctly
 mangled name, the former is merely a symbolic reference.

 There are two options for generating the correct import library, safe
 one, and flexible one.

 The safe method is available if you have a COFF (MS-compatible) import
 library for your DLL.  Then you use
 http://www.digitalmars.com/ctg/coffimplib.html
 to convert it into an OMF import library usable with DMD.  Then simply
 use whatever export() generates the right names for your lib.

 The flexible method is to use
 http://www.dprogramming.com/linkdef.php
 to create an import library based upon the linker errors produced by
 DMD.  Beware though that it's your responsibility to choose the correct
 extern() calling convention.  DLL does not have any calling convention
 meta-data, so linkdef will link any undefined symbols to the similarly
 named symbols in a DLL without any compatibility guarantee.

If you have the DLL, I've always had success creating the DMD COFF import library for it using "implib" in the basic utils package. Usually you'll need to create it using the /system flag. If that doesn't work try it without the /system flag.

I'll tell you what happens next. You create an import library: implib kernel32.lib c:\windows\system32\kernel32.dll /system Then you declare a function: extern (System) HANDLE CreateFileA(...); and linker fails because it expects "_CreateFileA 28" which is not in your library, there's only "_CreateFileA". Then you change your declaration to extern (C) HANDLE CreateFileA(...); Everything compiles but you get your stack corrupted because CreateFileA is stdcall and unwinds stack, but extern(C) is cdecl so your code contains stack unwinding, too. So you clean stack twice.
Sep 17 2008
prev sibling next sibling parent "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On Wed, 17 Sep 2008 01:02:59 +0200, Bill Baxter <wbaxter gmail.com> wrote:

 I believe the scoping was changed so that the extern(): block  no
 longer continued to the end of file.  The fix added to make everyones
 programs compile again was "extern(System):" which can be used without
 a version block, and basically acts like "extern(Windows):" on windows
 and "extern(C):" everywhere else.

 --bb

Thanks, but that don't seem to fix my problem. However, you might be onto something, as the name mangling seems wrong. _glClear should be _glClear 4 and so on. A quick search tells me the first is __cdecl and the latter __stdcall. Moving the declarations from gl/gl.d to my source file fixed all problems. Bug? -- Simen
Sep 17 2008
prev sibling parent "Bill Baxter" <wbaxter gmail.com> writes:
On Wed, Sep 17, 2008 at 11:37 PM, Sergey Gromov <snake.scaly gmail.com> wrote:
 Simen Kjaeraas <simen.kjaras gmail.com> wrote:
 On Wed, 17 Sep 2008 01:02:59 +0200, Bill Baxter <wbaxter gmail.com> wrote:

 I believe the scoping was changed so that the extern(): block  no
 longer continued to the end of file.  The fix added to make everyones
 programs compile again was "extern(System):" which can be used without
 a version block, and basically acts like "extern(Windows):" on windows
 and "extern(C):" everywhere else.

 --bb

Thanks, but that don't seem to fix my problem. However, you might be onto something, as the name mangling seems wrong. _glClear should be _glClear 4 and so on. A quick search tells me the first is __cdecl and the latter __stdcall. Moving the declarations from gl/gl.d to my source file fixed all problems. Bug?

Maybe it's the same problem I've had hit recently. The names in DLL exports are not mangled according to the calling convention rules. I.e. kernel32.dll exports CreateFileA although it's _CreateFileA 28 in Microsoft's kernel32.lib. The latter is a correctly mangled name, the former is merely a symbolic reference. There are two options for generating the correct import library, safe one, and flexible one. The safe method is available if you have a COFF (MS-compatible) import library for your DLL. Then you use http://www.digitalmars.com/ctg/coffimplib.html to convert it into an OMF import library usable with DMD. Then simply use whatever export() generates the right names for your lib. The flexible method is to use http://www.dprogramming.com/linkdef.php to create an import library based upon the linker errors produced by DMD. Beware though that it's your responsibility to choose the correct extern() calling convention. DLL does not have any calling convention meta-data, so linkdef will link any undefined symbols to the similarly named symbols in a DLL without any compatibility guarantee.

If you have the DLL, I've always had success creating the DMD COFF import library for it using "implib" in the basic utils package. Usually you'll need to create it using the /system flag. If that doesn't work try it without the /system flag. --bb
Sep 17 2008