Re: C++ Interfacing:'static' array function parameter contradiction
On Friday, 28 April 2017 at 18:41:22 UTC, kinke wrote: On Friday, 28 April 2017 at 18:07:49 UTC, ParticlePeter wrote: Interesting, your example corresponds to my third case, the linker error. I am on Window, building an x64 App, afaik in that case the MS Visual Studio linker is used instead of optilink. Will add your findings to the bug report. Apparently Microsoft's C++ compiler doesn't mangle `float arg[3]` parameters identically to `float* arg`: void cppSArray(float color[3]) => ?cppSArray@@YAXQEAM@Z void cppPtr(float* color) => ?cppPtr@@YAXPEAM@Z The worst part about that is mangling aside, the two declarations are identical to the compiler. Atila
Re: C++ Interfacing:'static' array function parameter contradiction
On Friday, 28 April 2017 at 19:08:18 UTC, ParticlePeter wrote: On Friday, 28 April 2017 at 17:57:34 UTC, Ali Çehreli wrote: On 04/28/2017 08:56 AM, ParticlePeter wrote: > C++ Function: > bool cppFunc( float[3] color ); > > D binding: > extern(C++) bool cppFunc( float[3] color ); > > Using with: > float[3] my_color; > cppFunc( my_color ); > > -> Error: Internal Compiler Error: unable to pass static array to That part is a bug at least in the compiler message. Is it really an internal ctompiler error? Doesn't look like it: the compiler is talking to us happily. :) My simple test works for me: // deneme.cpp float cppFunc(float color[3]) { return color[0] + color[1] + color[2]; } $ g++ -c deneme.cpp -o deneme_cpp.o // deneme.d extern(C++) float cppFunc(float * color); void main() { float[3] my_color = [ 1.5, 2.5, 3.5 ] ; assert(cppFunc(my_color.ptr) == 7.5); } $ dmd deneme_cpp.o deneme.d -of=deneme Builds and runs fine... on Linux... I don't know whether that's significant. Ali Btw, according to [1] your example should not work either, I doubt that there is a difference between C and C++ interfacing, it should be: extern(C++) float cppFunc( ref float[3] color ); In my case its a linker error as well. [1] http://dlang.org/spec/interfaceToC.html#passing_d_array If you are having problems with the linker with Ali's you can do ``` extern(C++) bool cppFunc( float[3] color ); // correct signature, but causes compiler error pragma(mangle, cppFunc.mangleof) float cppFunc(float * color); // compatible signature but wrong mangling overridden with pragma(mangle,...)
Re: COM Expertise needed: COM Callbacks
On Friday, 28 April 2017 at 09:25:31 UTC, John Chapman wrote: On Thursday, 27 April 2017 at 20:20:23 UTC, Nierjerson wrote: QueryInterface is COM's version of opCast. It asks if you support the interface represented by an IID (riid). If you don't, then you return E_NOINTERFACE. If you do, then you point the result (pvObject) to yourself and return S_OK. Here's a basic implementation: extern(Windows) HRESULT QueryInterface(IID* riid, void** pvObject) { if (pvObject is null) return E_POINTER; *pvObject = null; if (*riid == IID_IUnknown) *pvObject = cast(void*)cast(IUnknown)this; else if (*riid == IID_IDispatch) *pvObject = cast(void*)cast(IDispatch)this; // and so on for all interfaces we support if (*pvObject is null) return E_NOINTERFACE; (cast(IUnknown)this).AddRef(); return S_OK; } Your code works. I had something similar but I think I was returning a null pointer on IID_Unknown or something similar. I now get a different error but it is a COM error rather than access violation. (error 80020009)
Re: COM Expertise needed: COM Callbacks
On Friday, 28 April 2017 at 09:25:31 UTC, John Chapman wrote: On Thursday, 27 April 2017 at 20:20:23 UTC, Nierjerson wrote: I think the main issue though, is that I really don't know what is going on when I invoke the PS function. It seems to call the server method that takes the interface and then the server does it's "magic"(which is calling my QueryInterface) but how the implemented QueryInterface is suppose to respond is beyond me... I've tried some based stuff but nothing seem to work. The good news is that it is doing something(calling QueryInterface) which means that the server is at work. Any more ideas? I think the issue currently is is the QueryInterface(it is simply not doing what it is suppose to). I'll probably have to look at some other implementations to see what is going on. QueryInterface is COM's version of opCast. It asks if you support the interface represented by an IID (riid). If you don't, then you return E_NOINTERFACE. If you do, then you point the result (pvObject) to yourself and return S_OK. Here's a basic implementation: extern(Windows) HRESULT QueryInterface(IID* riid, void** pvObject) { if (pvObject is null) return E_POINTER; *pvObject = null; if (*riid == IID_IUnknown) *pvObject = cast(void*)cast(IUnknown)this; else if (*riid == IID_IDispatch) *pvObject = cast(void*)cast(IDispatch)this; // and so on for all interfaces we support if (*pvObject is null) return E_NOINTERFACE; (cast(IUnknown)this).AddRef(); return S_OK; } Ok, I tried this and returned this but it didn't work. I didn't clal AddRef though, but maybe I was in the right direction but had some other issue. AddRef/Release perform the COM object's reference counting, so you should implement them too. However, I don't understand why your icRBCColor class both implements and encapsulates IDispatch - the generated version cRGBColor from Gen.d just encapsulates it. Why do you need to instantiate an instance of icRGBColor? Can't you just use the rgb1 object you got from the dd.RGB() getter, assign the colour values to its Red, Blue, Green properties as needed, then call the dd.RGB(rgb1) setter? Does that not work? cRGBColor and any class in Gen.d are not COM interfaces and can't be used. All they do is wrap the dynamic method invocation work that is required to interact with PS. It may work that I could use them to set the values and then reset the instance but I feel that seems to be a waste. There is no need to really set the object if one is using the property setters. Although my method of creating a "direct" COM interface wrapper(one that inherits from IDispatch and simply delegates the work to the original com) seems to do basically the same, I plan on converting those COM Properties in to D properties and maintain state on both ends that are always in sync(possibly a bit slow, but should be easy to implement and allow one to work with COM in a more D like fashion. I could, for example, just have those "c" classes inherit from IDispatch directly and then pass on the IDispatch COM calls to the underlying COM interface(which is stored in the c class). That would be a sort of combination of the two methods above and might be better as it avoids actually having to get any of the callback COM stuff working(the stuff I'm having a problem with now). I just wasn't sure if this method would work and didn't want to mess with the gen code too much before I had a better understanding of what is going on. Regardless, getting the above code to work is still important as it will explain to me how it should work so that I understand for future purposes if this method does not go that route. Thanks, I'll try to get it to work a again and report back.
get parameters of a function
Hi all, I have a question about the Parameters trait from https://dlang.org/phobos/std_traits.html#Parameters The following code does not compile. Why? import std.traits : Parameters; void main() { static assert(is(Parameters!S1 == Parameters!S2)); } struct S1 { auto opCall() {} auto opCall(int i){} } struct S2 { auto opCall(int i){} auto opCall() {} } So, of course, if I change the both opCall methods, e. g. in S1 it will. But I'm wondering, how to use the trait in this case? Is it mainly assumed to use it with functions without overloads?
Re: C++ Interfacing:'static' array function parameter contradiction
On Friday, 28 April 2017 at 17:57:34 UTC, Ali Çehreli wrote: On 04/28/2017 08:56 AM, ParticlePeter wrote: > C++ Function: > bool cppFunc( float[3] color ); > > D binding: > extern(C++) bool cppFunc( float[3] color ); > > Using with: > float[3] my_color; > cppFunc( my_color ); > > -> Error: Internal Compiler Error: unable to pass static array to That part is a bug at least in the compiler message. Is it really an internal ctompiler error? Doesn't look like it: the compiler is talking to us happily. :) My simple test works for me: // deneme.cpp float cppFunc(float color[3]) { return color[0] + color[1] + color[2]; } $ g++ -c deneme.cpp -o deneme_cpp.o // deneme.d extern(C++) float cppFunc(float * color); void main() { float[3] my_color = [ 1.5, 2.5, 3.5 ] ; assert(cppFunc(my_color.ptr) == 7.5); } $ dmd deneme_cpp.o deneme.d -of=deneme Builds and runs fine... on Linux... I don't know whether that's significant. Ali Btw, according to [1] your example should not work either, I doubt that there is a difference between C and C++ interfacing, it should be: extern(C++) float cppFunc( ref float[3] color ); In my case its a linker error as well. [1] http://dlang.org/spec/interfaceToC.html#passing_d_array
Re: C++ Interfacing:'static' array function parameter contradiction
On Friday, 28 April 2017 at 18:07:49 UTC, ParticlePeter wrote: Interesting, your example corresponds to my third case, the linker error. I am on Window, building an x64 App, afaik in that case the MS Visual Studio linker is used instead of optilink. Will add your findings to the bug report. Apparently Microsoft's C++ compiler doesn't mangle `float arg[3]` parameters identically to `float* arg`: void cppSArray(float color[3]) => ?cppSArray@@YAXQEAM@Z void cppPtr(float* color) => ?cppPtr@@YAXPEAM@Z
Re: problem with std.variant rounding
On Fri, Apr 28, 2017 at 04:42:28PM +, via Digitalmars-d-learn wrote: [...] > writefln(text("%.", i, "f"), x); [...] There's no need to use text() here: writefln("%.*f", i, x); does what you want. T -- "You know, maybe we don't *need* enemies." "Yeah, best friends are about all I can take." -- Calvin & Hobbes
Re: C++ Interfacing:'static' array function parameter contradiction
On Friday, 28 April 2017 at 17:57:34 UTC, Ali Çehreli wrote: On 04/28/2017 08:56 AM, ParticlePeter wrote: > C++ Function: > bool cppFunc( float[3] color ); > > D binding: > extern(C++) bool cppFunc( float[3] color ); > > Using with: > float[3] my_color; > cppFunc( my_color ); > > -> Error: Internal Compiler Error: unable to pass static array to That part is a bug at least in the compiler message. Is it really an internal ctompiler error? Doesn't look like it: the compiler is talking to us happily. :) My simple test works for me: // deneme.cpp float cppFunc(float color[3]) { return color[0] + color[1] + color[2]; } $ g++ -c deneme.cpp -o deneme_cpp.o // deneme.d extern(C++) float cppFunc(float * color); void main() { float[3] my_color = [ 1.5, 2.5, 3.5 ] ; assert(cppFunc(my_color.ptr) == 7.5); } $ dmd deneme_cpp.o deneme.d -of=deneme Builds and runs fine... on Linux... I don't know whether that's significant. Ali Interesting, your example corresponds to my third case, the linker error. I am on Window, building an x64 App, afaik in that case the MS Visual Studio linker is used instead of optilink. Will add your findings to the bug report.
Re: C++ Interfacing:'static' array function parameter contradiction
On 04/28/2017 08:56 AM, ParticlePeter wrote: > C++ Function: > bool cppFunc( float[3] color ); > > D binding: > extern(C++) bool cppFunc( float[3] color ); > > Using with: > float[3] my_color; > cppFunc( my_color ); > > -> Error: Internal Compiler Error: unable to pass static array to That part is a bug at least in the compiler message. Is it really an internal ctompiler error? Doesn't look like it: the compiler is talking to us happily. :) My simple test works for me: // deneme.cpp float cppFunc(float color[3]) { return color[0] + color[1] + color[2]; } $ g++ -c deneme.cpp -o deneme_cpp.o // deneme.d extern(C++) float cppFunc(float * color); void main() { float[3] my_color = [ 1.5, 2.5, 3.5 ] ; assert(cppFunc(my_color.ptr) == 7.5); } $ dmd deneme_cpp.o deneme.d -of=deneme Builds and runs fine... on Linux... I don't know whether that's significant. Ali
Re: C++ Interfacing:'static' array function parameter contradiction
On Friday, 28 April 2017 at 17:15:54 UTC, kinke wrote: On Friday, 28 April 2017 at 15:56:17 UTC, ParticlePeter wrote: So what next? How can I interface to the cpp function? *** C++: bool cppFunc(float ()[3]) { color[0] = 1; color[1] = 2; color[2] = 3; return true; } *** D: extern(C++) bool cppFunc(ref float[3] color); void main() { float[3] my_color; cppFunc(my_color); assert(my_color == [ 1, 2, 3 ]); } The c++ lib is not mine and your answer implies extra work on the c++ from my side. Possible, but not desired, I think calling my original c++ function should interface with an d pointer. That being said, I think Kagamin is right.
Re: C++ Interfacing:'static' array function parameter contradiction
On Friday, 28 April 2017 at 15:56:17 UTC, ParticlePeter wrote: So what next? How can I interface to the cpp function? *** C++: bool cppFunc(float ()[3]) { color[0] = 1; color[1] = 2; color[2] = 3; return true; } *** D: extern(C++) bool cppFunc(ref float[3] color); void main() { float[3] my_color; cppFunc(my_color); assert(my_color == [ 1, 2, 3 ]); }
Re: problem with std.variant rounding
On Friday, 28 April 2017 at 16:42:28 UTC, Petar Kirov [ZombineDev] wrote: On Friday, 28 April 2017 at 16:24:55 UTC, Suliman wrote: On Friday, 28 April 2017 at 15:45:25 UTC, Suliman wrote: I am using https://github.com/mysql-d/mysql-native It's return from DB variant data-type. My DB include value: 56.051151 (double type in DB) I need to extract it. I tried several variants: writeln(point[3].coerce!float); writeln(point[3].coerce!string); writeln(point[3].coerce!double); but all of them return me it as: 56.0512 How to return exactly 56.051151 ? import std.stdio; import std.variant; void main() { Variant b = 56.051151; float x = b.coerce!float; writeln(x); } 56.0512 The precision is still there, you're just not requesting it: import std.conv : text; import std.stdio; import std.variant; void main() { Variant b = 56.051151; float x = b.coerce!float; foreach (i; 0 .. 10) writefln(text("%.", i, "f"), x); } 56 56.1 56.05 56.051 56.0512 56.05115 56.051151 56.0511513 56.05115128 56.051151276 How to return exactly 56.051151 ? Specify the number of digits after the decimal point manually, e.g. writefln("%.6f", x) will print 56.051151. BTW, you should always try to use the same floating-point type, so if you use 64-bit doubles in the database, you should also use double in your D code, otherwise you may accumulate rounding errors after each conversion. When converting to smaller floating-point types (real -> double and double -> float) you are essentially throwing out precision. For example: import std.conv : text; import std.stdio; import std.variant; void main() { Variant b = 56.051151; foreach (i; 0 .. 16) { writefln(text("%.", i, "f"), b.coerce!float); writefln(text("%.", i, "f"), b.coerce!double); } } Notice how the floats and doubles differ at i >= 6. 56 56 56.1 56.1 56.05 56.05 56.051 56.051 56.0512 56.0512 56.05115 56.05115 56.051151 56.051151 56.0511513 56.0511510 56.05115128 56.05115100 56.051151276 56.051151000 56.0511512756 56.051151 56.05115127563 56.0511510 56.051151275635 56.05115100 56.0511512756348 56.051151000 56.05115127563477 56.051151 56.051151275634766 56.0511507
Re: problem with std.variant rounding
On Friday, 28 April 2017 at 16:49:18 UTC, kinke wrote: On Friday, 28 April 2017 at 16:24:55 UTC, Suliman wrote: import std.stdio; import std.variant; void main() { Variant b = 56.051151; float x = b.coerce!float; writeln(x); } 56.0512 void main() { import core.stdc.stdio; import std.stdio; double d = 56.051151; writeln(d); printf("%g %f %a\n\n", d, d, d); real r = 56.051151L; writeln(r); printf("%Lg %Lf %La\n", r, r, r); } => 56.0512 56.0512 56.051151 0x1.c068c1db0142fp+5 56.0512 56.0512 56.051151 0x1.c068c1db0142f61ep+5 So using write[ln]() to check floating-point values isn't a good idea as you may lose precision; hex formatting (or a proper debugger) is a much better choice. Additionally, your value isn't *exactly* representable; you may want to read up on floating-point representations if that's unclear. Yeah! It was issue with rounding during writeln
Re: problem with std.variant rounding
On Friday, 28 April 2017 at 16:24:55 UTC, Suliman wrote: import std.stdio; import std.variant; void main() { Variant b = 56.051151; float x = b.coerce!float; writeln(x); } 56.0512 void main() { import core.stdc.stdio; import std.stdio; double d = 56.051151; writeln(d); printf("%g %f %a\n\n", d, d, d); real r = 56.051151L; writeln(r); printf("%Lg %Lf %La\n", r, r, r); } => 56.0512 56.0512 56.051151 0x1.c068c1db0142fp+5 56.0512 56.0512 56.051151 0x1.c068c1db0142f61ep+5 So using write[ln]() to check floating-point values isn't a good idea as you may lose precision; hex formatting (or a proper debugger) is a much better choice. Additionally, your value isn't *exactly* representable; you may want to read up on floating-point representations if that's unclear.
Re: C++ Interfacing:'static' array function parameter contradiction
Report a bug.
Re: problem with std.variant rounding
On Friday, 28 April 2017 at 16:24:55 UTC, Suliman wrote: On Friday, 28 April 2017 at 15:45:25 UTC, Suliman wrote: I am using https://github.com/mysql-d/mysql-native It's return from DB variant data-type. My DB include value: 56.051151 (double type in DB) I need to extract it. I tried several variants: writeln(point[3].coerce!float); writeln(point[3].coerce!string); writeln(point[3].coerce!double); but all of them return me it as: 56.0512 How to return exactly 56.051151 ? import std.stdio; import std.variant; void main() { Variant b = 56.051151; float x = b.coerce!float; writeln(x); } 56.0512 The precision is still there, you're just not requesting it: import std.conv : text; import std.stdio; import std.variant; void main() { Variant b = 56.051151; float x = b.coerce!float; foreach (i; 0 .. 10) writefln(text("%.", i, "f"), x); } 56 56.1 56.05 56.051 56.0512 56.05115 56.051151 56.0511513 56.05115128 56.051151276 How to return exactly 56.051151 ? Specify the number of digits after the decimal point manually, e.g. writefln("%.6f", x) will print 56.051151.
Re: problem with std.variant rounding
On Friday, 28 April 2017 at 15:45:25 UTC, Suliman wrote: I am using https://github.com/mysql-d/mysql-native It's return from DB variant data-type. My DB include value: 56.051151 (double type in DB) I need to extract it. I tried several variants: writeln(point[3].coerce!float); writeln(point[3].coerce!string); writeln(point[3].coerce!double); but all of them return me it as: 56.0512 How to return exactly 56.051151 ? import std.stdio; import std.variant; void main() { Variant b = 56.051151; float x = b.coerce!float; writeln(x); } 56.0512
Re: Persistent key-value-store for D?
On Friday, 28 April 2017 at 16:01:58 UTC, yawniek wrote: On Wednesday, 26 April 2017 at 17:06:52 UTC, krylon wrote: I looked at the DUB package registry and asked Google quite a bit now, but I did not found such a package for D. So my first question is - did I not look hard enough? I found a reimplentation of QDBM [1] (the spiritual ancestor of Tokyocabinet), but it does not seem to handle concurrency at all. Are there other options along those lines? (If there was one that also provides transactions, that would be awesome!) If I understand what I have read so far correctly, it is possible to access libraries written in C or C++ from D - in that case, I could just use Tokyocabinet directly, but I have not found any pointers on how to do this. Is this a feasible option, and if so, where can I find documentation on how to do this? i recommend leveldb http://code.dlang.org/packages/d-leveldb its easy to use and mostly faster than tokyocabinet ( only very specifically tuned tokyo btrees outperform leveldb) i used above library with great success. it also shows you how to do c bindings. Thank you for the suggestion! For the moment I am using LMDB, as suggested in another reply, and it works well. LevelDB seems to have a cleaner interface, though, at least in D. I'll keep that in mind for future projects.
Re: Persistent key-value-store for D?
On Wednesday, 26 April 2017 at 17:06:52 UTC, krylon wrote: I looked at the DUB package registry and asked Google quite a bit now, but I did not found such a package for D. So my first question is - did I not look hard enough? I found a reimplentation of QDBM [1] (the spiritual ancestor of Tokyocabinet), but it does not seem to handle concurrency at all. Are there other options along those lines? (If there was one that also provides transactions, that would be awesome!) If I understand what I have read so far correctly, it is possible to access libraries written in C or C++ from D - in that case, I could just use Tokyocabinet directly, but I have not found any pointers on how to do this. Is this a feasible option, and if so, where can I find documentation on how to do this? i recommend leveldb http://code.dlang.org/packages/d-leveldb its easy to use and mostly faster than tokyocabinet ( only very specifically tuned tokyo btrees outperform leveldb) i used above library with great success. it also shows you how to do c bindings.
C++ Interfacing:'static' array function parameter contradiction
C++ Function: bool cppFunc( float[3] color ); D binding: extern(C++) bool cppFunc( float[3] color ); Using with: float[3] my_color; cppFunc( my_color ); -> Error: Internal Compiler Error: unable to pass static array to extern(C++) function. Error: Use pointer instead. Using with: cppFunc( my_color.ptr ); -> Error: function cppFunc( float[3] color ) is not callable using argument types (float*) Altering D binding: extern(C++) bool cppFunc( float* color ); Using with: cppFunc( my_color.ptr ); -> error LNK2001: unresolved external symbol "bool __cdecl cppFunc(float *)" Binding.exe : fatal error LNK1120: 1 unresolved externals Error: linker exited with status 1120 dmd failed with exit code 1120. So what next? How can I interface to the cpp function?
problem with std.variant rounding
I am using https://github.com/mysql-d/mysql-native It's return from DB variant data-type. My DB include value: 56.051151 (double type in DB) I need to extract it. I tried several variants: writeln(point[3].coerce!float); writeln(point[3].coerce!string); writeln(point[3].coerce!double); but all of them return me it as: 56.0512 How to return exactly 56.051151 ?
Re: COM Expertise needed: COM Callbacks
On Thursday, 27 April 2017 at 20:20:23 UTC, Nierjerson wrote: I think the main issue though, is that I really don't know what is going on when I invoke the PS function. It seems to call the server method that takes the interface and then the server does it's "magic"(which is calling my QueryInterface) but how the implemented QueryInterface is suppose to respond is beyond me... I've tried some based stuff but nothing seem to work. The good news is that it is doing something(calling QueryInterface) which means that the server is at work. Any more ideas? I think the issue currently is is the QueryInterface(it is simply not doing what it is suppose to). I'll probably have to look at some other implementations to see what is going on. QueryInterface is COM's version of opCast. It asks if you support the interface represented by an IID (riid). If you don't, then you return E_NOINTERFACE. If you do, then you point the result (pvObject) to yourself and return S_OK. Here's a basic implementation: extern(Windows) HRESULT QueryInterface(IID* riid, void** pvObject) { if (pvObject is null) return E_POINTER; *pvObject = null; if (*riid == IID_IUnknown) *pvObject = cast(void*)cast(IUnknown)this; else if (*riid == IID_IDispatch) *pvObject = cast(void*)cast(IDispatch)this; // and so on for all interfaces we support if (*pvObject is null) return E_NOINTERFACE; (cast(IUnknown)this).AddRef(); return S_OK; } AddRef/Release perform the COM object's reference counting, so you should implement them too. However, I don't understand why your icRBCColor class both implements and encapsulates IDispatch - the generated version cRGBColor from Gen.d just encapsulates it. Why do you need to instantiate an instance of icRGBColor? Can't you just use the rgb1 object you got from the dd.RGB() getter, assign the colour values to its Red, Blue, Green properties as needed, then call the dd.RGB(rgb1) setter? Does that not work?
Re: Understanding lvalue and rvalue
On Friday, 28 April 2017 at 05:21:26 UTC, ag0aep6g wrote: Instead of removing `in`/`const` from the ref overload, you can also add it to the non-ref overload. Again, the overloads will have the same match level ("match with conversion to const"), and the ref version will win. It works. I don't know why I've decided to make rvalue parameter non-const. It makes sense. It's clear answer. Thank you very much!