digitalmars.D.learn - Shared library string safety?
- Mineko (21/21) Jan 13 2014 Alright, so I FINALLY got shared libraries somewhat working
- evilrat (8/29) Jan 13 2014 are you set your gc proxies for shared libs, right?
- Mineko (2/34) Jan 13 2014 Wow, um, that actually worked, thank you.
- Mineko (3/3) Jan 13 2014 Sorry for the double post, I should be more specific.
- evilrat (37/40) Jan 13 2014 the reason string.dup worked is due to GC on app side, right
- Mineko (9/46) Jan 13 2014 I see, I'll have to look more into that, on a slightly unrelated
- evilrat (12/21) Jan 14 2014 are you using derelict for this?
- TheFlyingFiddle (19/28) Jan 14 2014 glfwCreateWindow returns a null ptr if something is wrong with
- evilrat (17/22) Jan 14 2014 i've looked up in your sources on github and not found derelict
- Mineko (15/40) Jan 14 2014 I'm pretty sure it's initialized here:
- Mike Parker (46/48) Jan 14 2014 Yes, please do this. For DerelictGLFW3.load, it's just a matter of style...
- Mike Parker (4/6) Jan 14 2014 Actually, scratch that. DerelictGL3.reload does depend on the context
- Mineko (5/12) Jan 14 2014 Ahhh thank you, I'm currently away from my computer so I couldn't
Alright, so I FINALLY got shared libraries somewhat working through my program, however I have some issues transferring data between the shared library and the main program, the problem is between https://github.com/MinekoRox/Breaker-Engine/blob/master/src/breake /utility/settings.d and https://github.com/MinekoRox/Breaker-Engine/blob/master/res/scripts/core/settings.d The settings script is loaded by https://github.com/MinekoRox/Breaker-Engine/blob/master/src/breaker/utility/core.d And, this is the error I get: +start(string[]) Starting up the program 800600 ����B Shutting off the program Writing logs to disk ERROR: Error(s) occured, check the error log -start(string[]) +stop() Segmentation fault (core dumped) The 800600 is width and height, the problem is the binary output of what's supposed to be a string.
Jan 13 2014
On Tuesday, 14 January 2014 at 05:50:37 UTC, Mineko wrote:Alright, so I FINALLY got shared libraries somewhat working through my program, however I have some issues transferring data between the shared library and the main program, the problem is between https://github.com/MinekoRox/Breaker-Engine/blob/master/src/breake /utility/settings.d and https://github.com/MinekoRox/Breaker-Engine/blob/master/res/scripts/core/settings.d The settings script is loaded by https://github.com/MinekoRox/Breaker-Engine/blob/master/src/breaker/utility/core.d And, this is the error I get: +start(string[]) Starting up the program 800600 ����B Shutting off the program Writing logs to disk ERROR: Error(s) occured, check the error log -start(string[]) +stop() Segmentation fault (core dumped) The 800600 is width and height, the problem is the binary output of what's supposed to be a string.are you set your gc proxies for shared libs, right? if not, i think it would be safer to do string.dup(as with other arrays) when moving them between shared lib boundaries. but still keep in mind that current GC may not handle properly multiple intances. p.s. i don't do shared libs for non-Windows platform for a long time now, so it may be outdated info for now...
Jan 13 2014
On Tuesday, 14 January 2014 at 06:40:52 UTC, evilrat wrote:On Tuesday, 14 January 2014 at 05:50:37 UTC, Mineko wrote:Wow, um, that actually worked, thank you.Alright, so I FINALLY got shared libraries somewhat working through my program, however I have some issues transferring data between the shared library and the main program, the problem is between https://github.com/MinekoRox/Breaker-Engine/blob/master/src/breake /utility/settings.d and https://github.com/MinekoRox/Breaker-Engine/blob/master/res/scripts/core/settings.d The settings script is loaded by https://github.com/MinekoRox/Breaker-Engine/blob/master/src/breaker/utility/core.d And, this is the error I get: +start(string[]) Starting up the program 800600 ����B Shutting off the program Writing logs to disk ERROR: Error(s) occured, check the error log -start(string[]) +stop() Segmentation fault (core dumped) The 800600 is width and height, the problem is the binary output of what's supposed to be a string.are you set your gc proxies for shared libs, right? if not, i think it would be safer to do string.dup(as with other arrays) when moving them between shared lib boundaries. but still keep in mind that current GC may not handle properly multiple intances. p.s. i don't do shared libs for non-Windows platform for a long time now, so it may be outdated info for now...
Jan 13 2014
Sorry for the double post, I should be more specific. .dup worked, I don't know how to have the GC proxy for shared libs though.
Jan 13 2014
On Tuesday, 14 January 2014 at 06:48:48 UTC, Mineko wrote:Sorry for the double post, I should be more specific. .dup worked, I don't know how to have the GC proxy for shared libs though.the reason string.dup worked is due to GC on app side, right after the moment your lib receive the original string it is may be marked by GC for collection, so you need to save a copy on lib side. but using the proxies it should work without copying. for windows here is the topic about this http://dlang.org/dll.html for *nix platforms it should be the same. in short(pseudocode): ========================== app.d extern(C) void* gc_getProxy(); void main() { loadlib(); initLib( gc_getProxy() ); ... do something ... libFinalize(); } ------------------ lib.d extern (C) { void gc_setProxy(void* p); void gc_clrProxy(); } export void initLib(void* gc) { gc_setProxy(gc); } export void libFinalize() { gc_clrProxy(); } ========================== as i said i don't know about current status of shared libs, but there was some progress on linux and Windows, and unfortunatelly not OS X...
Jan 13 2014
On Tuesday, 14 January 2014 at 07:23:52 UTC, evilrat wrote:the reason string.dup worked is due to GC on app side, right after the moment your lib receive the original string it is may be marked by GC for collection, so you need to save a copy on lib side. but using the proxies it should work without copying. for windows here is the topic about this http://dlang.org/dll.html for *nix platforms it should be the same. in short(pseudocode): ========================== app.d extern(C) void* gc_getProxy(); void main() { loadlib(); initLib( gc_getProxy() ); ... do something ... libFinalize(); } ------------------ lib.d extern (C) { void gc_setProxy(void* p); void gc_clrProxy(); } export void initLib(void* gc) { gc_setProxy(gc); } export void libFinalize() { gc_clrProxy(); } ========================== as i said i don't know about current status of shared libs, but there was some progress on linux and Windows, and unfortunatelly not OS X...I see, I'll have to look more into that, on a slightly unrelated note, any idea what's going on with glfwCreateWindow, it keeps wanting to be null while it's supposed to be an adddress. this.get = glfwCreateWindow(settings.width, settings.height, toStringz(settings.title), this.monitor, this.share); writeln(this.get); That writeln will give me null, is it related to all this stuff?
Jan 13 2014
On Tuesday, 14 January 2014 at 07:44:21 UTC, Mineko wrote:I see, I'll have to look more into that, on a slightly unrelated note, any idea what's going on with glfwCreateWindow, it keeps wanting to be null while it's supposed to be an adddress. this.get = glfwCreateWindow(settings.width, settings.height, toStringz(settings.title), this.monitor, this.share); writeln(this.get); That writeln will give me null, is it related to all this stuff?are you using derelict for this? do you really need fullscreen and sharing contexts? try to call this to get non-fullscreen window without sharing (just peronal, but also it may be a bit more readeble using UFCS on toStringz) this.get = glfwCreateWindow(settings.width, settings.height, settings.title.toStringz(), null, null); if that work for you then problem is due to sharing which may require context(which you probably don't have or trying to share with itself), or due to driver issues related to fullscreen mode if on linux, but i'm unsure about the later.
Jan 14 2014
On Tuesday, 14 January 2014 at 07:44:21 UTC, Mineko wrote:I see, I'll have to look more into that, on a slightly unrelated note, any idea what's going on with glfwCreateWindow, it keeps wanting to be null while it's supposed to be an adddress. this.get = glfwCreateWindow(settings.width, settings.height, toStringz(settings.title), this.monitor, this.share); writeln(this.get);glfwCreateWindow returns a null ptr if something is wrong with it's parameters or os driver or anything it can detect really. To get error information you can use glfwSetErrorCallback with a custom function and handle the errors with it. Something like this: extern(C) void errorFunc(int error_code, const(char)* errorMessage) { //Do something here like wrilteln. } void main() { //Load libs and setup stuff. glfwSetErrorCallback(&errorFunc); //Now anything that gives an error will forward it to //errorFunc. }That writeln will give me null, is it related to all this stuff?I doubt it.
Jan 14 2014
On Tuesday, 14 January 2014 at 07:44:21 UTC, Mineko wrote:this.get = glfwCreateWindow(settings.width, settings.height, toStringz(settings.title), this.monitor, this.share); writeln(this.get); That writeln will give me null, is it related to all this stuff?i've looked up in your sources on github and not found derelict initiliazation. i recommend loading glfw in relevant module with module ctor. most if non all derelict bindings has dynamic loading, don't forget to load and init derelict 'plugins' if necessary. ---------------- module window; static this() { DerelictGLFW.load(); } class Window { ... using GLFW here ... } --------------
Jan 14 2014
On Tuesday, 14 January 2014 at 09:35:11 UTC, evilrat wrote:On Tuesday, 14 January 2014 at 07:44:21 UTC, Mineko wrote:I'm pretty sure it's initialized here: https://github.com/MinekoRox/Breaker-Engine/blob/master/src/breaker/utility/belt.d /** Initialize GLFW */ auto initGLFW() { import breaker.main : timer; DerelictGLFW3.load; if (!glfwInit) return false; timer.time = 0.0001; return true; } Perhaps I should be using () with GLFW3.load and glfwInit? I'll try a static loading though, sure.this.get = glfwCreateWindow(settings.width, settings.height, toStringz(settings.title), this.monitor, this.share); writeln(this.get); That writeln will give me null, is it related to all this stuff?i've looked up in your sources on github and not found derelict initiliazation. i recommend loading glfw in relevant module with module ctor. most if non all derelict bindings has dynamic loading, don't forget to load and init derelict 'plugins' if necessary. ---------------- module window; static this() { DerelictGLFW.load(); } class Window { ... using GLFW here ... } --------------
Jan 14 2014
On 1/14/2014 9:10 PM, Mineko wrote:Perhaps I should be using () with GLFW3.load and glfwInit?Yes, please do this. For DerelictGLFW3.load, it's just a matter of style and doesn't make a difference. However, glfwInit is a *function pointer*, not a function.. So what you're effectively doing there is testing if the function pointer is null or not. You aren't actually calling the function. Since you already called DerelictGLFW3.load, then it obviously isn't null, so your method completes and returns true. Then later, when you call glfwCreateWindow, since the library was never initialized, it returns null. You could have saved yourself a lot of time by using an error callback as recommended earlier in this thread. And you should set the callback between DerelictGLFW3.load and glfwInit. extern(C) nothrow void onErr(int code, const(char)* msg) { // log the message, but be aware that you may need to wrap // it in a try...catch block, since the callback has to be // nothrow. } auto initGLFW() { import breaker.main : timer; DerelictGLFW3.load; glfwSetErrorCallback( &onErr ); // Add the parens here!!!!!!!! if ( !glfwInit() ) return false; timer.time = 0.0001; return true; } Do this and you'll get an error message if any glfw function call fails. And always keep in mind that when using Derelict, the library functions you call are all function pointers. That means this function: auto glfwTerm() {return glfwTerminate;} Is returning a function pointer. It isn't calling anything. You need to add parens here, too. In fact, I strongly recommend you use parens everywhere unless you are calling properties. Speaking of which, why would you make glfwTerm a property? One more bit of advice. In initGL, you have this: DerelictGL3.load; glfwMakeContextCurrent(window.get); DerelictGL3.reload; The call to glfwMakeContextCurrent doesn't need to be there. For ease of maintenance, I suggest you move it to the method where you call glfwCreateWindow. That way, initGL does not depend on the window already being created. You don't need to load DerelictGL3 before calling it.I'll try a static loading though, sure.This won't make a difference.
Jan 14 2014
On 1/14/2014 9:55 PM, Mike Parker wrote:That way, initGL does not depend on the window already being created.Actually, scratch that. DerelictGL3.reload does depend on the context already being created. However, the call to glfwMakeContextCurrent still should be in the same spot you create the window.
Jan 14 2014
On Tuesday, 14 January 2014 at 12:58:04 UTC, Mike Parker wrote:On 1/14/2014 9:55 PM, Mike Parker wrote:Ahhh thank you, I'm currently away from my computer so I couldn't do much as far as my code goes, but I'll certainly do all of that, I always have trouble with functions and function pointers haha. :PThat way, initGL does not depend on the window already being created.Actually, scratch that. DerelictGL3.reload does depend on the context already being created. However, the call to glfwMakeContextCurrent still should be in the same spot you create the window.
Jan 14 2014