Re: Using .lib and .dll in D applications
On Sunday, 19 June 2016 at 18:33:36 UTC, moe wrote: On Sunday, 19 June 2016 at 18:00:07 UTC, Mike Parker wrote: On Sunday, 19 June 2016 at 17:33:43 UTC, moe wrote: Unfortunatelly I still don't get it. I would like to have an independant project "dbar". The created lib is then used in another project "dfoo". Assuming that "dfoo" has no access to "dbar" other than the .lib file. You can't do it with only the lib file. You *need* the source file too for the import statement. As I explained, the lib file is used by the linker, not the compiler. The compiler needs the source file. My folder structure is like this: -dtest --dbar source\barlib.d dub.json This project creates a dbar.lib file which seams to work. -dtest --dfoo lib\dbar.d // copied from the dbar project source\app.d dub.json You don't need to copy dbar to the lib directory in this case. This project would use the dbar.lib but should otherwise not have access to the dbar project. Basically simulating, that someone else made a dbar project to which I would not have access other than using the dbar.lib. How do I have to configure the dub.json file for this to work? One of two things would happen: 1) They would register the project with he dub registry, then you add a dependency to a specific version the library. Dub would then download the necessary files for you and ensure that everything you need is passed to the compiler when building your project. 2) They would provide some other means for you to get the source and the library. Then you would need to manually configure your dub.json to pass the import path to the compiler and link with the library. I have tried a variety of configurations for the dub.json. At this point it feels like a bad guessing game. That is no way to deveop anything. I need to figure out how to properly setup the dub.json but I don't seam to find the answer online. "http://code.dlang.org/package-format?lang=json"; isn't very helpful. All the information you need is there on that page. I have meanwhile adjusted my dtest/dfoo/dub.json to this: "dependencies": { "dbar": "~master" } This gives me the error: "Root package dfoo references unknown package dear" As I explained above, you need a path attribute for the dependency in this case since it is on your local file system and not in the registry. The documentation link I gave you explains how to to this. Try this: "dependencies": { "dbar": {"path": "../dbar"} } I see where I went wrong. I thought that it's possible to only use the .lib file without the source code of dbar. Having access to the source makes what I am trying somewhat pointless. Is it otherwise possible to provide some functionality without having to give away your source? I would like to put together a library that I can reuse, without having to rely on the source each time. Maybe a dll instead? Note: I don't have a problem with giving away my code. I just want to know if it can be done. Or maybe later build a plugin system where the creator of the plugin does not need the source of the entire application. And in turn the app does not need to be recompiled in order to use the plugin. Thanks for your help! Sure, you can just have a file with "extern" functions that tells the compiler that the source for those functions isn't available at compile time, but that later on when you link the library, the linker will find those function definitions in the .lib file (I'm not a Windows expert, but from my understanding .DLLs are a different ball game, and have to be loaded and called with special functions in your app.) In your example, in your "dfoo.d", you can declare the functions from the dbar.lib inside as "extern myfunction();" and the compiler will say, "OK, myfunction() isn't defined here, so we'll let the linker sort it out." If you try and compile without telling it about dbar.lib, you'll get errors like "undefined reference to myfunction()...". When you see that somebody wrote a "binding" in D for a library like OpenGL, etc., this is what they are providing, a .d file filled with "extern" definitions and maybe some glue code to convert D types into C types if the .lib file is a C library. APIs generally work the same way. Library writers will provide a .h header file that doesn't expose any of their closed source, but gives users of the library the definitions of the functions they need to use it's functions. I hope this helps! -Jon
Re: What exactly does the compiler switch -betterC do?
On Sunday, 19 June 2016 at 19:53:46 UTC, Gary Willoughby wrote: When compiling, what exactly does the -betterC flag do? The command help says "omit generating some runtime information and helper functions" but what does this really mean? Is there any specifics somewhere? My understanding was that -betterC was not fully implemented yet, due mostly to tight compiler integration with the runtime. (old info?) I'm not super smart on the DMD source, but it looks like betterC prevents genhelpers() and genModuleInfo() from being called, with "helpers" appearing to be array checking, asserts and unit tests. A comparison of object files compiled with and without the flags shows just a small reduction in the size of the code, but grepping for bounds checking, unit tests and ModuleInfo in the -betterC generated object file shows they are missing. Hope this helps, -Jon
Re: Linker error
On Sunday, 5 June 2016 at 21:26:56 UTC, Anonymous wrote: On Sunday, 5 June 2016 at 21:16:36 UTC, Andrej Mitrovic wrote: On 6/5/16, Anonymous via Digitalmars-d-learn wrote: Should I report this as a dmd bug then? Not sure where / how to do that. You can report it here: https://issues.dlang.org I think I'll just let it go; I was able to work passed it anyway using "static Note[] empty;", and `null` works too. Is either one better? null is simpler from a reader's perspective. :) By the way, this is from an example I found in "D Web Development" by Kai Nacke. Interesting that they would use such code in the book. Which chapter is it? Thanks. I agree it's simpler and switched to `null`. The example is in chapter 3. That it works on OSX but not on Windows makes me think it should definitely be reported as a bug. -Jon
Re: Embed files into binary.
On Monday, 6 June 2016 at 02:05:09 UTC, Pie? wrote: I saw somewhere someone explaining how to embed resources into a binary using the import keyword. I believe the essentially converted the file into a ubyte or something and then wrote that out to a temp file and read in the temp file... this seems a bit of a kludge to me. Is it possible to do the same, but create a sort of "in memory" file layout? While I can modify my own routines to read the "file" from memory, I can't do that easily with outside code(I could modify the binaries). Basically reading a file has to read it to memory, and if the file data already exists in memory, there is no point to read, just get it direct. Any thoughts on this? Because D allows such an embedding feature, maybe the file system should allow working with this concept? That way, it becomes VERY easy to embed files into the binary and work with them like they wernt. Also, going between the two different versions(embedded vs not) could be done with version (Release). I'm not sure about import, but one option is to put the external files directly in your binary as part of the linker step. Check out: http://www.linuxjournal.com/content/embedding-file-executable-aka-hello-world-version-5967 On Windows I think there's a way to embed files in .DLLs and then link those into your executable, but I'm ignorant of the steps/tools required. -Jon
Re: Linker error
On Sunday, 5 June 2016 at 18:36:13 UTC, Anonymous wrote: On Sunday, 5 June 2016 at 18:30:25 UTC, Anonymous wrote: [...] Should have included: OPTLINK (R) for Win32 Release 8.00.17 Copyright (C) Digital Mars 1989-2013 All rights reserved. http://www.digitalmars.com/ctg/optlink.html ns.obj(ns) Offset 0BA0AH Record Type 009D Error 16: Index Range --- errorlevel 1 Hmm, on OSX w/ dmd v2.071.0 I'm unable to duplicate. Can you try upgrading to v2.071 and see if that works? -Jon
Re: Quite sure a simple basic problem...
On Thursday, 2 June 2016 at 00:37:58 UTC, WhatMeWorry wrote: I've got a fairly complex D project (25+ modules) that has grown haphazardly over time. So it is not well designed. But I want to get the thing fully ported before refining the code. (that's called refactoring, I believe?) Anyway, there is a new module called audio.d which which has all the sound functionality. And in the (main.d) module is a code snippet like so void main(string[] argv) { // . . . auto blop = new AlurePlaySound("../bleep.wav"); blop.play(); // . . . } So all is well and good except I need to place the sound in another module (game.d) where collisions are detected. I tried: module game; import main; // is this as ugly as I think it is? if (collision[0]) // If collision make sound blop.play(); but this returns: game.d(501): Error: undefined identifier 'blop' So can someone tell me what various solutions to this problem or type of problems? I presume there are quick and dirty solutions (like here) and more elegant solutions? Would this type of problem fall under the domain of "scope". Like in global scope. But I don't think D has such a concept. Thanks. Since blop is being declared inside your main() function, it isn't visible to other modules or functions. You're right that the issue is a problem of "scope". Importing your main module will work, but you must declare your as a global variable outside the main() function. i.e. -- module main; AlurePlaySound blop; void main() { //etc... blop = new AlurePlaySound("../beep.wav"); //etc... } -- module game; import main; void collision() { blop.play(); //or whatever } If your game loop is running in a separate thread, then I think you'll want to use: __gshared AlurePlaySound blop; for the declaration, since variables are thread-local by default. Using global variables is generally frowned upon for production code because you can never be sure which functions are modifying it. But for a quick hack, it works! A better option might be to make a third module with a class containing all your audio objects, initialize it in main(), and then pass it to your main game loop. -Jon