Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
January 04, 2015 Need extern (C) interface even though using Derelict GLFW | ||||
---|---|---|---|---|
| ||||
I've been translating C++, OpenGL, and GLUT code into D, Derelict OpenGL, and Derelict GLFW using: import derelict.opengl3.gl3; import derelict.glfw3.glfw3; auto window = glfwCreateWindow(800, 600, "Shaders", null, null); etc. Things have been going well. I then tried to implement window resizing with a callback function and the glfwSetWindowSizeCallback() statement. void windowResizeCallback(GLFWwindow* window, int width, int height) { glViewport(0, 0, width, height); } and glfwSetWindowSizeCallback(window, &windowResizeCallback); however, I kept getting the following compiler error: Error 1 Error: function pointer glfwSetWindowSizeCallback (GLFWwindow*, extern (C) void function(GLFWwindow*, int, int) nothrow) is not callable using argument types (GLFWwindow*, void function(GLFWwindow* window, int width, int height)) Well, I was able to get it to compile and work by adding the following "decoration" extern (C) nothrow { void windowResizeCallback(GLFWwindow* window, int width, int height) { glViewport(0, 0, width, height); } } Now it resizes the screen successfully, but I feel like I've failed by using extern (C) nothrow. Shouldn't Derelict GLFW be providing a D interface? Maybe GLFW callback functions can't handled through Derelict GLFW? |
January 04, 2015 Re: Need extern (C) interface even though using Derelict GLFW | ||||
---|---|---|---|---|
| ||||
Posted in reply to WhatMeWorry | On 4/01/2015 5:34 p.m., WhatMeWorry wrote:
>
> I've been translating C++, OpenGL, and GLUT code into D, Derelict
> OpenGL, and Derelict GLFW using:
>
> import derelict.opengl3.gl3;
> import derelict.glfw3.glfw3;
>
> auto window = glfwCreateWindow(800, 600, "Shaders", null, null);
>
> etc.
>
>
> Things have been going well. I then tried to implement window resizing
> with a callback function and the glfwSetWindowSizeCallback() statement.
>
>
> void windowResizeCallback(GLFWwindow* window, int width, int height)
> {
> glViewport(0, 0, width, height);
> }
>
> and
>
> glfwSetWindowSizeCallback(window, &windowResizeCallback);
>
>
> however, I kept getting the following compiler error:
> Error 1 Error: function pointer glfwSetWindowSizeCallback
> (GLFWwindow*, extern (C) void function(GLFWwindow*, int, int) nothrow)
> is not callable using argument types (GLFWwindow*, void
> function(GLFWwindow* window, int width, int height))
>
> Well, I was able to get it to compile and work by adding the following
> "decoration"
>
> extern (C) nothrow
> {
> void windowResizeCallback(GLFWwindow* window, int width, int height)
> {
> glViewport(0, 0, width, height);
> }
> }
>
>
> Now it resizes the screen successfully, but I feel like I've failed by
> using extern (C) nothrow. Shouldn't Derelict GLFW be providing a D
> interface?
>
> Maybe GLFW callback functions can't handled through Derelict GLFW?
No this is correct code.
Derelict projects are just bindings. Which means the c equivalent in D. Nothing more nothing less.
|
January 04, 2015 Re: Need extern (C) interface even though using Derelict GLFW | ||||
---|---|---|---|---|
| ||||
Posted in reply to WhatMeWorry | On 1/4/2015 1:34 PM, WhatMeWorry wrote:
>
> Now it resizes the screen successfully, but I feel like I've failed by
> using extern (C) nothrow. Shouldn't Derelict GLFW be providing a D
> interface?
>
> Maybe GLFW callback functions can't handled through Derelict GLFW?
>
>
Derelict provides direct bindings, not wrappers. Any of the Derelict packages can be used as the core of a wrapper that provides a more D-like API, but that's beyond the scope of the Derelict project.
|
January 04, 2015 Re: Need extern (C) interface even though using Derelict GLFW | ||||
---|---|---|---|---|
| ||||
Posted in reply to WhatMeWorry | On 1/4/2015 1:34 PM, WhatMeWorry wrote:
> Maybe GLFW callback functions can't handled through Derelict GLFW?
>
>
And just to be clear, because the pointers to the callback functions are being passed to a C API, they *have* to be extern( C ) -- i.e. they have to have the same calling convention that the C library expects. If the library functions used the stdcall calling convention rather than cdecl, then the callbacks would have to be extern( Windows ). So even a wrapper that allows you to pass D delegates or function pointers would still have to internally give GLFW a pointer to a function with the proper calling convention.
|
January 04, 2015 Re: Need extern (C) interface even though using Derelict GLFW | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Parker | On Sunday, 4 January 2015 at 09:02:48 UTC, Mike Parker wrote:
> On 1/4/2015 1:34 PM, WhatMeWorry wrote:
>
>> Maybe GLFW callback functions can't handled through Derelict GLFW?
>>
>>
> And just to be clear, because the pointers to the callback functions are being passed to a C API, they *have* to be extern( C ) -- i.e. they have to have the same calling convention that the C library expects. If the library functions used the stdcall calling convention rather than cdecl, then the callbacks would have to be extern( Windows ). So even a wrapper that allows you to pass D delegates or function pointers would still have to internally give GLFW a pointer to a function with the proper calling convention.
Thanks for the replies. I felt like I was creating a kludge.
I have to confess that the above paragraph is pretty much incomprehensible to me. Except for "function pointers" the rest of the terms I have seen before, but can't really make out into a meaningful whole.
Are they some extremely simple tutorials on bindings and wrappers? Something with lots of code examples.
|
January 05, 2015 Re: Need extern (C) interface even though using Derelict GLFW | ||||
---|---|---|---|---|
| ||||
Posted in reply to WhatMeWorry | On 5/01/2015 9:30 a.m., WhatMeWorry wrote:
> On Sunday, 4 January 2015 at 09:02:48 UTC, Mike Parker wrote:
>> On 1/4/2015 1:34 PM, WhatMeWorry wrote:
>>
>>> Maybe GLFW callback functions can't handled through Derelict GLFW?
>>>
>>>
>> And just to be clear, because the pointers to the callback functions
>> are being passed to a C API, they *have* to be extern( C ) -- i.e.
>> they have to have the same calling convention that the C library
>> expects. If the library functions used the stdcall calling convention
>> rather than cdecl, then the callbacks would have to be extern( Windows
>> ). So even a wrapper that allows you to pass D delegates or function
>> pointers would still have to internally give GLFW a pointer to a
>> function with the proper calling convention.
>
> Thanks for the replies. I felt like I was creating a kludge.
>
>
> I have to confess that the above paragraph is pretty much
> incomprehensible to me. Except for "function pointers" the rest of the
> terms I have seen before, but can't really make out into a meaningful
> whole.
>
> Are they some extremely simple tutorials on bindings and wrappers?
> Something with lots of code examples.
I'll use luad as an example.
Luad has both bindings and a wrapper to lua in it.
Primarily you will use the wrapper.
The bindings provide access directly to the c api.
The wrapper makes the API nice to use in D.
A binding is not meant to be nice to use.
It is meant to be equivalent to the original.
|
January 05, 2015 Re: Need extern (C) interface even though using Derelict GLFW | ||||
---|---|---|---|---|
| ||||
Posted in reply to WhatMeWorry | > > Are they some extremely simple tutorials on bindings and wrappers? Something with lots of code examples. I don't think it's a subject that warrants a tutorial. There's not that much to it. Consider: #### // capi.h void do_something( const char *str ); // capi.d -- this is a binding extern( C ) void do_something( const( char )* str ); // capiwrapper.d -- this is a wrapper void doSomething( string str ) { import std.string : toStringz; do_something( str.toStringz() ); } #### That's all there is to it. The binding allows you to call C functions from D. The wrapper adds a more convenient D interface on top of the C function. Of course, there are numerous details to consider when implementing a binding (some of which you can see at [1]), but you generally don't need to worry about them as a user. There are exceptions, though, when you need to be aware of what's going on. One of those is when implementing callbacks. All you really need to understand is that the calling convention of the C functions may not be the same as that of D functions. That's why the C function above is decorated with extern( C ) -- it uses the cdecl calling convention (see [2] for an explanation of different x86 calling conventions). So any callbacks you pass into the API need to be of the same calling convention, because they are actually being called on the C side, not the D side. [1] http://dlang.org/interfaceToC.html [2] http://en.wikipedia.org/wiki/X86_calling_conventions |
Copyright © 1999-2021 by the D Language Foundation