Re: A strange charArray.ptr behavior
On Wednesday, 2 December 2020 at 21:01:22 UTC, Ali Çehreli wrote: On 12/2/20 12:20 PM, Ferhat Kurtulmuş wrote: given the function: export void ceaser_enc(char* input, ref char* output); this compiles: char* sezar = (new char[65]).ptr; ceaser_enc(key, sezar); this does not compile: char[] sezar = new char[65]; ceaser_enc(key, sezar.ptr); by yielding: "cannot pass rvalue argument cast(char*)sezar of type char* to parameter ref char* output" Why is sezar an rvalue in the second case? Not 'sezar' but sezar.ptr is an rvalue. Imagine ptr() being a function that returns a value: T* ptr() { // ... } That pointer is an rvalue and D disallows binding them to 'ref' parameters. In the first case, 'sezar' is a local variable, which is an lvalue. Ali That makes sense. Thank you.
Re: My first application in Dlang
On Thursday, 3 December 2020 at 02:44:40 UTC, Ali Çehreli wrote: On 12/2/20 5:46 PM, Marcone wrote: Hello, my name is Marcone, I live in Brazil, and I have been studying Dlang for a year. I finished my first application in Dlang with a graphical interface in Win32api and made it available on the internet for anyone who wants to download it. Here is the program link. As a beginner in the D programming language, I would like a note from you who have been D programmers for a long time if I am doing well. What did you think about the application? Link of my First Aplication created with Dlang and Win32api : https://sourceforge.net/projects/direct-http-tunnel/ Thank you. Cool. :) But did you want to share your *source* code? All I see there is a .exe, which I would not start due to risk of viruses (of course unknown to you). Ali Hi, are you Ali Çehreli author of Programming in D book? I learned Dlang by reading this book on my Kindle. If I published my source code you wouldn't understand. I created a module with functions so useful, that using UFCS if it weren't for the keys delimiting the blocks, anyone would think they're reading a Python code.
Re: My first application in Dlang
On 12/2/20 5:46 PM, Marcone wrote: Hello, my name is Marcone, I live in Brazil, and I have been studying Dlang for a year. I finished my first application in Dlang with a graphical interface in Win32api and made it available on the internet for anyone who wants to download it. Here is the program link. As a beginner in the D programming language, I would like a note from you who have been D programmers for a long time if I am doing well. What did you think about the application? Link of my First Aplication created with Dlang and Win32api : https://sourceforge.net/projects/direct-http-tunnel/ Thank you. Cool. :) But did you want to share your *source* code? All I see there is a .exe, which I would not start due to risk of viruses (of course unknown to you). Ali
My first application in Dlang
Hello, my name is Marcone, I live in Brazil, and I have been studying Dlang for a year. I finished my first application in Dlang with a graphical interface in Win32api and made it available on the internet for anyone who wants to download it. Here is the program link. As a beginner in the D programming language, I would like a note from you who have been D programmers for a long time if I am doing well. What did you think about the application? Link of my First Aplication created with Dlang and Win32api : https://sourceforge.net/projects/direct-http-tunnel/ Thank you.
Re: D Bindings for C Opaque Pointers
On Thursday, 3 December 2020 at 01:19:05 UTC, bachmeier wrote: On Thursday, 3 December 2020 at 00:30:06 UTC, Kyle Ingraham wrote: What did I do wrong in constructing the bindings? If it helps the library provides a function called EdsRelease for cleaning-up allocated objects. Is the management of pointers between D and C the issue? Please forgive me if I've mangled that concept. Not an answer to your question, but the "idiomatic" approach is to not write bindings yourself. dstep generates bindings: https://github.com/jacob-carlborg/dstep dpp lets you include C header files directly: https://github.com/atilaneves/dpp Thanks for the suggestions here. I had no idea that these tools existed. Now that I've gotten my feet wet with doing it manually it'll be interesting to compare results with those from automation. I'm all for it they can take some of the heavy lifting away.
Re: D Bindings for C Opaque Pointers
On Thursday, 3 December 2020 at 00:58:20 UTC, Paul Backus wrote: On Thursday, 3 December 2020 at 00:30:06 UTC, Kyle Ingraham wrote: // EDSDKTypes.h typedef struct __EdsObject* EdsBaseRef; typedef EdsBaseRef EdsCameraListRef; // [...] // edsdk.d struct EdsBaseRef; alias EdsBaseRef EdsCameraListRef; You've dropped a level of indirection here. In the C header, EdsBaseRef is a pointer, but in your D code, it is an opaque struct. The correct way to translate these C declarations into D is: struct __EdsObject; alias EdsBaseRef = __EdsObject*; alias EdsCameraListRef = EdsBaseRef; Note that unlike C, D does not allow us to refer to an incomplete type without first declaring it. That did it. The binding works without issue now. Thanks a ton for the direction. I'll keep that distinction between C and D in mind as I go forward. It's been night and day between D and C++. I struggled for a while getting this work going in C++ but was firmly blocked by CMake. D and dub have been champs for ease of use.
Re: D Bindings for C Opaque Pointers
On Thursday, 3 December 2020 at 00:30:06 UTC, Kyle Ingraham wrote: What did I do wrong in constructing the bindings? If it helps the library provides a function called EdsRelease for cleaning-up allocated objects. Is the management of pointers between D and C the issue? Please forgive me if I've mangled that concept. Not an answer to your question, but the "idiomatic" approach is to not write bindings yourself. dstep generates bindings: https://github.com/jacob-carlborg/dstep dpp lets you include C header files directly: https://github.com/atilaneves/dpp
Re: D Bindings for C Opaque Pointers
On Thursday, 3 December 2020 at 00:30:06 UTC, Kyle Ingraham wrote: // EDSDKTypes.h typedef struct __EdsObject* EdsBaseRef; typedef EdsBaseRef EdsCameraListRef; // [...] // edsdk.d struct EdsBaseRef; alias EdsBaseRef EdsCameraListRef; You've dropped a level of indirection here. In the C header, EdsBaseRef is a pointer, but in your D code, it is an opaque struct. The correct way to translate these C declarations into D is: struct __EdsObject; alias EdsBaseRef = __EdsObject*; alias EdsCameraListRef = EdsBaseRef; Note that unlike C, D does not allow us to refer to an incomplete type without first declaring it.
D Bindings for C Opaque Pointers
Hello all. I am new to D and loving the experience so far. I am trying to make use of a C library from Canon that provides a header and a pre-compiled binary containing implementations of declarations found in the header. I used the excellent guide at https://www.gamedev.net/articles/programming/general-and-gameplay-programming/binding-d-to-c-r3122/ to get started and so far I can initialize the library and embed it within my D application. So far so great! Where I am running into problems is creating D bindings for this function declaration: // EDSDK.h EdsError EDSAPI EdsGetCameraList(EdsCameraListRef* outCameraListRef); // If accepts a pointer to EdsCameraListRef that is declared as: // EDSDKTypes.h typedef struct __EdsObject* EdsBaseRef; typedef EdsBaseRef EdsCameraListRef; // From my reading I learned that EdsCameraListRef is an alias of an alias for an opaque pointer. It allowed the library writers to declare an object for use that the end-user would not have access to the implementation of. These are the D bindings I created: // edsdk.d struct EdsBaseRef; alias EdsBaseRef EdsCameraListRef; alias uint EdsUInt32; extern (System): EdsError EdsGetCameraList(EdsCameraListRef*); EdsError EdsGetChildCount(EdsBaseRef*, EdsUInt32*); EdsUInt32 EdsRelease(EdsBaseRef*); // Calling the functions using the bindings and the following code results in invalid pointer errors however (reported from the library): // camera_list.d import edsdk; class CameraList { private EdsCameraListRef* list; private EdsUInt32 _count = 0; this() { // Returns EDS_ERR_INVALID_POINTER EdsGetCameraList(list); // Returns EDS_ERR_INVALID_HANDLE EdsGetChildCount(list, &_count); } ~this() { EdsRelease(list); } final uint count() { return cast(uint) _count; } } // What did I do wrong in constructing the bindings? If it helps the library provides a function called EdsRelease for cleaning-up allocated objects. Is the management of pointers between D and C the issue? Please forgive me if I've mangled that concept.
Re: Anybody know if I can build DMD with Visual Studio 2019?
On Tuesday, 1 December 2020 at 22:58:53 UTC, WhatMeWorry wrote: I'm trying to build DMD with Visual D under Visual Studio as shown in the Wiki: https://wiki.dlang.org/Building_under_Windows The notes say to use the solution vcbuild: You should be able to build DMD using the visual studio solution found in: dmd\src\vcbuild A typical choice is to build the 64-bit debug version (the VisualD options are named 'Release' and 'x64'). [Btw, Should that be "64-bit release version" or "'Debug' and 'x64'"?] I do this with Visual Studio 2019 and I'm getting errors. Should I be using Visual Studio 2017 or even VS 2013? Didn't want to waste time debugging if VS2019 is not supported. It works now. Not sure what I did to _not_ make it work yesterday.
Re: A strange charArray.ptr behavior
On 12/2/20 12:20 PM, Ferhat Kurtulmuş wrote: given the function: export void ceaser_enc(char* input, ref char* output); this compiles: char* sezar = (new char[65]).ptr; ceaser_enc(key, sezar); this does not compile: char[] sezar = new char[65]; ceaser_enc(key, sezar.ptr); by yielding: "cannot pass rvalue argument cast(char*)sezar of type char* to parameter ref char* output" Why is sezar an rvalue in the second case? Not 'sezar' but sezar.ptr is an rvalue. Imagine ptr() being a function that returns a value: T* ptr() { // ... } That pointer is an rvalue and D disallows binding them to 'ref' parameters. In the first case, 'sezar' is a local variable, which is an lvalue. Ali
Re: How to build dll?
On Wednesday, 2 December 2020 at 20:08:29 UTC, Jack wrote: On Wednesday, 2 December 2020 at 19:42:37 UTC, Jack wrote: D code: [...] compiled with: [...] called from: [...] but hinstLib is NULL and GetLastError() = 193: [...] What am I missing? for same reason, the dll build with ldc2 works fine, compiled with: ldc2 -shared dll.d -ofmydll.dll what am I missing? Just out of curiosity, are you sure that you compile both your c and d codes for the same arc?
A strange charArray.ptr behavior
given the function: export void ceaser_enc(char* input, ref char* output); this compiles: char* sezar = (new char[65]).ptr; ceaser_enc(key, sezar); this does not compile: char[] sezar = new char[65]; ceaser_enc(key, sezar.ptr); by yielding: "cannot pass rvalue argument cast(char*)sezar of type char* to parameter ref char* output" Why is sezar an rvalue in the second case?
Re: How to build dll?
On Wednesday, 2 December 2020 at 19:42:37 UTC, Jack wrote: D code: import core.sys.windows.dll; mixin SimpleDllMain; version(Windows) extern(C) export int foo() { return 42; } compiled with: dmd -ofmydll.dll -shared -m32 dll.d called from: typedef int (__cdecl *MYPROC)(void); int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR szCmdLine, int CmdShow) { HINSTANCE hinstLib; MYPROC ProcAdd; BOOL fFreeResult, fRunTimeLinkSuccess = FALSE; // Get a handle to the DLL module. hinstLib = LoadLibrary(TEXT("mydll.dll")); but hinstLib is NULL and GetLastError() = 193: ERROR_BAD_EXE_FORMAT 193 (0xC1) %1 is not a valid Win32 application. What am I missing? for same reason, the dll build with ldc2 works fine, compiled with: ldc2 -shared dll.d -ofmydll.dll what am I missing?
Re: How make Optional pre determined parameter type without overload function?
Now my slice works fine. // Tipo Nulo. class None {} // Função slice() auto slice(T1, T2, T3 = None)(T1 conteudo, T2 inicio, T3 fim = T3.init) { int start, end, startlen; static if (is(T2 == int)) {inicio = inicio < 0 ? conteudo.length + inicio : inicio;} static if (is(T3 == int)) {fim = fim <= 0 ? conteudo.length + fim : fim;} static if (is(T2 == int)) {start = inicio;} else static if (is(T2 == string)){start = conteudo.countUntil(inicio);} static if (is(T2 == string)) {static if (is(T1 == string)){startlen = start + inicio.length + 1;} else {startlen = start + 1;}} static if (is(T3 == int)) {end = fim;} else static if (is(T3 == string)){end = startlen + conteudo[startlen..$].countUntil(fim);} static if (is(T3 == None)) {return conteudo[start];} else {return conteudo[start..end];} }
How to build dll?
D code: import core.sys.windows.dll; mixin SimpleDllMain; version(Windows) extern(C) export int foo() { return 42; } compiled with: dmd -ofmydll.dll -shared -m32 dll.d called from: typedef int (__cdecl *MYPROC)(void); int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR szCmdLine, int CmdShow) { HINSTANCE hinstLib; MYPROC ProcAdd; BOOL fFreeResult, fRunTimeLinkSuccess = FALSE; // Get a handle to the DLL module. hinstLib = LoadLibrary(TEXT("mydll.dll")); but hinstLib is NULL and GetLastError() = 193: ERROR_BAD_EXE_FORMAT 193 (0xC1) %1 is not a valid Win32 application. What am I missing?
invalid path to external symbolizer!
I try find a memory issue with ldc -betterC -g -fsanitize=address -disable-fp-elim, get invalid path to external symbolizer! Is there a way to print the symbol and line ? = ==113433==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x606008a0 at pc 0x0070dcf2 bp 0x7ffedf7514c0 sp 0x7ffedf7514b8 WRITE of size 8 at 0x606008a0 thread T0 ==113433==WARNING: invalid path to external symbolizer! ==113433==WARNING: Failed to use and restart external symbolizer! #0 0x70dcf1 (/root/ncore+0x70dcf1) #1 0x5bea1f (/root/ncore+0x5bea1f) #2 0x5be68b (/root/ncore+0x5be68b) #3 0x5bd626 (/root/ncore+0x5bd626) #4 0x7f7644 (/root/ncore+0x7f7644) #5 0x7fc078 (/root/ncore+0x7fc078) #6 0x7fc1cd (/root/ncore+0x7fc1cd) #7 0x5c1060 (/root/ncore+0x5c1060) #8 0x730f4f (/root/ncore+0x730f4f) #9 0x738dea (/root/ncore+0x738dea) #10 0x6c2a12 (/root/ncore+0x6c2a12) #11 0x6dbdc1 (/root/ncore+0x6dbdc1) #12 0x724fa3 (/root/ncore+0x724fa3) #13 0x6d1707 (/root/ncore+0x6d1707) #14 0x724bb6 (/root/ncore+0x724bb6) #15 0x7f8fb6dbd09a (/lib/x86_64-linux-gnu/libc.so.6+0x2409a) #16 0x4ea029 (/root/ncore+0x4ea029) 0x606008a0 is located 0 bytes to the right of 64-byte region [0x60600860,0x606008a0) allocated by thread T0 here: #0 0x562952 (/root/ncore+0x562952) #1 0x66c009 (/root/ncore+0x66c009) #2 0x70d991 (/root/ncore+0x70d991) #3 0x5bea1f (/root/ncore+0x5bea1f) #4 0x5be68b (/root/ncore+0x5be68b) #5 0x5bd626 (/root/ncore+0x5bd626) #6 0x7f7644 (/root/ncore+0x7f7644) #7 0x730f4f (/root/ncore+0x730f4f) #8 0x6dbdc1 (/root/ncore+0x6dbdc1) #9 0x724fa3 (/root/ncore+0x724fa3) #10 0x6d1707 (/root/ncore+0x6d1707) #11 0x724bb6 (/root/ncore+0x724bb6) #12 0x7f8fb6dbd09a (/lib/x86_64-linux-gnu/libc.so.6+0x2409a) SUMMARY: AddressSanitizer: heap-buffer-overflow (/root/ncore+0x70dcf1) Shadow bytes around the buggy address: 0x0c0c7fff80c0: fa fa fa fa fd fd fd fd fd fd fd fd fa fa fa fa 0x0c0c7fff80d0: 00 00 00 00 00 00 00 05 fa fa fa fa fd fd fd fd 0x0c0c7fff80e0: fd fd fd fa fa fa fa fa fd fd fd fd fd fd fd fa 0x0c0c7fff80f0: fa fa fa fa fd fd fd fd fd fd fd fa fa fa fa fa 0x0c0c7fff8100: fd fd fd fd fd fd fd fa fa fa fa fa 00 00 00 00 =>0x0c0c7fff8110: 00 00 00 00[fa]fa fa fa 00 00 00 00 00 00 00 07 0x0c0c7fff8120: fa fa fa fa fd fd fd fd fd fd fd fd fa fa fa fa 0x0c0c7fff8130: fd fd fd fd fd fd fd fd fa fa fa fa fd fd fd fd 0x0c0c7fff8140: fd fd fd fd fa fa fa fa fd fd fd fd fd fd fd fd 0x0c0c7fff8150: fa fa fa fa 00 00 00 00 00 00 00 00 fa fa fa fa 0x0c0c7fff8160: fd fd fd fd fd fd fd fd fa fa fa fa 00 00 00 00 Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user:f7 Container overflow: fc Array cookie:ac Intra object redzone:bb ASan internal: fe Left alloca redzone: ca Right alloca redzone:cb Shadow gap: cc ==113433==ABORTING
Re: IsTuple returns true for Nullable!SomeTuple
On Wednesday, 2 December 2020 at 12:59:52 UTC, Paul Backus wrote: No, this is not a bug, because Nullable!T currently has an implicit conversion to T via `alias this`. [1] However, this implicit conversion is deprecated, and will be removed in a future release. Once that happens, `isTuple!NT` will be `false`, as you'd expect. [1] http://phobos.dpldocs.info/std.typecons.Nullable.1.html#alias-this I guess it's a moot point because the implicit conversion is deprecated, but it seems strange to me that isTuple behaves like canBeUsedAsTuple. Seems like the reasonable thing to do with a Nullable!(Tuple!Whatever) would be to check isTuple!(TemplateArgsOf!MyNullable) Thanks for the response
Re: ParameterIdentifierTuple returns empty strings
On Wednesday, 2 December 2020 at 15:40:09 UTC, Adam D. Ruppe wrote: On Wednesday, 2 December 2020 at 11:46:26 UTC, Andre Pany wrote: [...] Function pointers don't really have parameter names. They are allowed for user habit and documentation purposes, but the compiler mostly* ignores them; they aren't actually part of the formal type. [...] Thanks for all the answers, this solves my issue. Kind regards Andre
Re: ParameterIdentifierTuple returns empty strings
On Wednesday, 2 December 2020 at 11:46:26 UTC, Andre Pany wrote: alias fpt = extern(C) nothrow void function(int a, int b); Function pointers don't really have parameter names. They are allowed for user habit and documentation purposes, but the compiler mostly* ignores them; they aren't actually part of the formal type. * I'm pretty sure I've seen some weird cases where it did work but I can't recall right now. So this alias erases the names before it does anything with them. This is useful, if you did like extern(C) nothrow void foo(int not_a, int not_b); fpt thing = &something; That assignment is still allowed because the names are not considered. Change anything else though and you get a type mismatch. Moreover, consider reflection on that. Are Parameters!thing `a, b` because of the alias, or `not_a, not_b` because of the function assigned? Pretty obvious it can't be the latter, because what the variable actually points to is not known at compile time. But then if it was the former that'd be kinda weird because it wouldn't match what you set. So I think think it is doing the best it can by just not giving the info. Now btw if you do want the names off `something`, ParameterIdentifierTuple!something would give you the not_a, not_b. Maybe you can use that in your code. If you pass a thing as an `alias` template parameter, without the & operator, it retains the names.
Re: ParameterIdentifierTuple returns empty strings
On Wednesday, 2 December 2020 at 11:46:26 UTC, Andre Pany wrote: Hi, I need to retrieve the parameter identifier but only empty strings are returned: tuple("", "") ``` d alias fpt = extern(C) nothrow void function(int a, int b); void main() { import std.traits : ParameterIdentifierTuple; pragma(msg, ParameterIdentifierTuple!(fpt)); } ``` Where is here the error? Kind regards André If you look at the template [1] implementation, function pointers are rejected, apparently because of a `__parameters` limitation. There something to report. Bad documentation at least. [1]: https://github.com/dlang/phobos/blob/2c0660141748a13637ff473cbb7b0d52eb1c44db/std/traits.d#L1400
Re: IsTuple returns true for Nullable!SomeTuple
On Wednesday, 2 December 2020 at 05:25:09 UTC, Ben Jones wrote: This seems like very surprising behavior to me. Is it a bug? import std.typecons; alias NT = Nullable!(Tuple!(int, double)); pragma(msg, isTuple!NT); //prints true! No, this is not a bug, because Nullable!T currently has an implicit conversion to T via `alias this`. [1] However, this implicit conversion is deprecated, and will be removed in a future release. Once that happens, `isTuple!NT` will be `false`, as you'd expect. [1] http://phobos.dpldocs.info/std.typecons.Nullable.1.html#alias-this
Re: Running unit tests from DUB single file packages
On 12/1/20 5:18 PM, Johannes Loher wrote: Am 01.12.20 um 14:55 schrieb drug: On 12/1/20 2:40 PM, Johannes Loher wrote: ... However, I am having trouble running the unit tests when using the ... This can be one of solution https://github.com/dlang/dub/pull/2050 Thanks! Let's see if it gets merged or if a slightly more involved solution is needed. Remake it - https://github.com/dlang/dub/pull/2052 This has more chances to be merged
ParameterIdentifierTuple returns empty strings
Hi, I need to retrieve the parameter identifier but only empty strings are returned: tuple("", "") ``` d alias fpt = extern(C) nothrow void function(int a, int b); void main() { import std.traits : ParameterIdentifierTuple; pragma(msg, ParameterIdentifierTuple!(fpt)); } ``` Where is here the error? Kind regards André
Re: Dude about ~ array concatenation performance
On Wednesday, 2 December 2020 at 06:31:49 UTC, H. S. Teoh wrote: On Tue, Dec 01, 2020 at 10:49:55PM +, ddcovery via Digitalmars-d-learn wrote: Yesterday I really shocked when, comparing one algorithm written in javascript and the equivalent in D, javascript performed better!!! [...] With 1 million Double numbers (generated randomly): Javascript (node 12): 1507 ms DMD: 2166 ms With 6 million Double numbers Javascript (node 12): 10776 ms DMD: 15243 ms Yeah, when it comes to performance-related things, don't bother with DMD. Its optimizer is known to have limitations, and IME consistently produces code that underperforms LDC-generated code by about 20-30%, sometimes even as high as 40%. For performance comparisons, always use GDC/LDC. T After applying adecuate parametrization (thanks to Max Haughton for the tips), LDC generated code is running almost 3 times faster than DMD one!!!