Re: call Pascal DLL functions from D
On Wednesday, 25 October 2017 at 03:12:56 UTC, Oleg B wrote: Hello. I have DLL written on Pascal and "headers" for use it (types and functions signatures definitions). How I can port "headers" to D? [...] Hi, this thread might be interesting for you, if you use Delphi http://forum.dlang.org/post/hpodoabutuakfxbzz...@forum.dlang.org This thread describes a bridge between the D Programming Language and Delphi. Kind regards André
Re: call Pascal DLL functions from D
On Wednesday, 25 October 2017 at 03:12:56 UTC, Oleg B wrote: Hello. I have DLL written on Pascal and "headers" for use it (types and functions signatures definitions). How I can port "headers" to D? Calling convention is `stdcall` (`extern (Windows)` for D), arguments of some functions is structs of structs and etc with static array fields: ```Pascal type TOneHarmonic = record Koef: Single; Angle: Single; end; THarmonicsArray = array[2..50] of TOneHarmonic; TInterharmonicsArray = array[1..49] of TOneHarmonic; TVoltageCurrentOneFaza = record KalibKoef: Single; IncludeMainFreq: Boolean; MainFreqVoltCur: TOneHarmonic; Harmonics: THarmonicsArray; Interharmonics: TInterharmonicsArray; end; TVoltageCurrent = record Enable: Boolean; NominalID: Byte; Faza_A: TVoltageCurrentOneFaza; Faza_B: TVoltageCurrentOneFaza; Faza_C: TVoltageCurrentOneFaza; end; TSignal = record HasInterharmonics: Boolean; Voltage: TVoltageCurrent; Current: TVoltageCurrent; ... end; ... ``` in other file ```Pascal function CheckSignalData(SignalData: PUserSignalData): Word; stdcall; external SIGNALK2MDLL; ``` PUserSignalData is pointer to TUserSignalData, first field of TUserSignalData is Signal, other fields is pointers to other types If I understand correctly 1. `Single` is `float` in D, `Byte` is `byte`, `Boolean` is `bool`, `Word` is `ushort` No Pascal's "Byte" is D's "ubyte". But unless NominalID goes over 127 this is not the source of the problem. 2. `array[A..B] of TFoo` is `TFoo[B-A+1]` (static array) No A-B. In Pascal the upper bound of a range (like here but i'm not sure this i called like that in the grammar) or of a slice is inclusive. Can I rewrite records to structs like this? ```d alias Word = short; alias Single = float; alias Byte = byte; alias Boolean = bool; struct OneHarmonic { Single coef; Single angle; } alias HarmonicArray = OneHarmonic[49]; 48 ! // TVoltageCurrentOneFaza struct PhaseInfo { // Must I align fields and/or structs? No, unless the record is packed. Single calibCoef; Boolean includeMainFreq; OneHarmonic mainFreqVoltCur; HarmonicArray harmonics; // Can I replace Pascal static arrays with D static arrays? HarmonicArray interharmonics; } // TVoltageCurrent struct ChannelInfo { Boolean enable; Byte nominalID; PhaseInfo[3] phase; // Can I replace 3 fields to static array? yes } struct Signal { Boolean hasInterharmonics; ChannelInfo voltage; ChannelInfo current; // #1 ... } ``` In this case I have error about current values (#1) and I think I badly rewrite Pascal records to D structs (ChannelInfo, PhaseInfo, OneHarmonic) and lose alignments and/or something else. PS original pascal naming is very bad, I know Most likely the problem is the array length.
Re: call Pascal DLL functions from D
On Wednesday, 25 October 2017 at 03:12:56 UTC, Oleg B wrote: Calling convention is `stdcall` (`extern (Windows)` for D), arguments of some functions is structs of structs and etc with static array fields: Fun fact, D has extern(Pascal): https://dlang.org/spec/attribute.html#linkage I don't know the details of the rest... but I think you're right about what you have so far. I'd suggest just trying it and seeing if the functions return what you expect.
call Pascal DLL functions from D
Hello. I have DLL written on Pascal and "headers" for use it (types and functions signatures definitions). How I can port "headers" to D? Calling convention is `stdcall` (`extern (Windows)` for D), arguments of some functions is structs of structs and etc with static array fields: ```Pascal type TOneHarmonic = record Koef: Single; Angle: Single; end; THarmonicsArray = array[2..50] of TOneHarmonic; TInterharmonicsArray = array[1..49] of TOneHarmonic; TVoltageCurrentOneFaza = record KalibKoef: Single; IncludeMainFreq: Boolean; MainFreqVoltCur: TOneHarmonic; Harmonics: THarmonicsArray; Interharmonics: TInterharmonicsArray; end; TVoltageCurrent = record Enable: Boolean; NominalID: Byte; Faza_A: TVoltageCurrentOneFaza; Faza_B: TVoltageCurrentOneFaza; Faza_C: TVoltageCurrentOneFaza; end; TSignal = record HasInterharmonics: Boolean; Voltage: TVoltageCurrent; Current: TVoltageCurrent; ... end; ... ``` in other file ```Pascal function CheckSignalData(SignalData: PUserSignalData): Word; stdcall; external SIGNALK2MDLL; ``` PUserSignalData is pointer to TUserSignalData, first field of TUserSignalData is Signal, other fields is pointers to other types If I understand correctly 1. `Single` is `float` in D, `Byte` is `byte`, `Boolean` is `bool`, `Word` is `ushort` 2. `array[A..B] of TFoo` is `TFoo[B-A+1]` (static array) Can I rewrite records to structs like this? ```d alias Word = short; alias Single = float; alias Byte = byte; alias Boolean = bool; struct OneHarmonic { Single coef; Single angle; } alias HarmonicArray = OneHarmonic[49]; // TVoltageCurrentOneFaza struct PhaseInfo { // Must I align fields and/or structs? Single calibCoef; Boolean includeMainFreq; OneHarmonic mainFreqVoltCur; HarmonicArray harmonics; // Can I replace Pascal static arrays with D static arrays? HarmonicArray interharmonics; } // TVoltageCurrent struct ChannelInfo { Boolean enable; Byte nominalID; PhaseInfo[3] phase; // Can I replace 3 fields to static array? } struct Signal { Boolean hasInterharmonics; ChannelInfo voltage; ChannelInfo current; // #1 ... } ``` In this case I have error about current values (#1) and I think I badly rewrite Pascal records to D structs (ChannelInfo, PhaseInfo, OneHarmonic) and lose alignments and/or something else. PS original pascal naming is very bad, I know
Re: Getting a safe path for a temporary file
On 10/22/2017 06:41 PM, Shriramana Sharma wrote: > On Sunday, 22 October 2017 at 15:21:37 UTC, Shriramana Sharma wrote: >> For my program right now I'm using a souped-up version using a static >> array: >> >> char[20] name = "/tmp/XX"; Literal strings have a '\0' attached, which does not become a part of the slice. > Hmm I was wondering if I needed it to be static, and verily, substituting: > > char[] name = "/tmp/XX".dup; However, .dup is not be aware of the special literal treatment so it does not copy the '\0' character. > Is it because the D slice is subject to relocation and C is occasionally > not able to access the proper pointer? As long as you have a reference on the D side, the slice will remain valid. The actual issue is the missing '\0'. So, consider toStringz in this case: https://dlang.org/library/std/string/to_stringz.html Ali
Re: DMD Callstacks
On Tuesday, 24 October 2017 at 06:49:37 UTC, abad wrote: On Monday, 23 October 2017 at 12:41:09 UTC, Márcio Martins wrote: What is everyone doing to get proper file name and line number info for callstacks with DMD? addr2line just gives me ??:0 You could try compiling with the -debug-switch. Of course if this turns out to be the fix, it doesn't help with std code. "-debug" activates the debug condition. To get file and line it's "-g" (generate debug infos), although this won't have any effect for phobos since the static library is already compiled.
Re: Address problem
On 10/24/2017 10:47 AM, Gheorghe Gabriel wrote: > writeln(&_i); That's the address of the local variable _i. You can think of class (and interface) variables as pointers to class objects. > I need that I["s"] to have the same address like c. The way to get the address of the actual object is to cast the class variable to void*. Here is your program with that change: import std.stdio; interface I { } I[string] i; class C : I { this() { i["s"] = this; foreach (_i; i) { writeln("value ", cast(void*)_i); } foreach (ref _i; i) { writeln("ref ", cast(void*)_i); } } } void main() { C c = new C; writeln("main ", cast(void*)c); assert(c is i["s"]); } Sample output for a 64-bit build: value 7FCE3EB23110 ref 7FCE3EB23110 main 7FCE3EB23100 The reason why main's is different is because c is an object as opposed to an interface. Apparently, it has extra 16 bytes of stuff before the interface part. Note the last line of main. Perhaps all you really need to do is to use the 'is' operator, which already takes care of such address calculations. Ali
Re: writeln double precision
On Tue, Oct 24, 2017 at 04:59:04PM +, jmh530 via Digitalmars-d-learn wrote: > On Tuesday, 24 October 2017 at 16:18:03 UTC, H. S. Teoh wrote: > > > > I have never seen a programming language in which dividing two > > integers yields a float or double. Either numbers default to a > > floating point type, in which case you begin with floats in the > > first place, or division is integer division, yielding an integer > > result. > > > > > > T > > Haven't used Python 3+? Haha, I guess I'm behind the times! T -- Gone Chopin. Bach in a minuet.
Address problem
Hi, --- interface I { } I[string] i; class C : I { this() { i["s"] = this; foreach (_i; i) { writeln(&_i); } foreach (ref _i; i) { writeln(&_i); } } } void main() { C c = new C; writeln(&c); } --- output: 19FDD8 2802028 21FE58 --- I need that I["s"] to have the same address like c.
Re: writeln double precision
On 10/24/2017 09:59 AM, Arun Chandrasekaran wrote: >>> On Monday, 23 October 2017 at 18:08:43 UTC, Ali Çehreli wrote: >>> > The rule is that every expression has a type and 22/7 is int. > I'm just questioning the reasoning behind why D does it this way and if > it is for compatibility or if there is any other reasoning behind the > decision. I'm not a language designer so I can't be sure but I think it has the same reasons that it has in C. The alternative would not be fit for a system language because we wouldn't know what types would be used for certain operations. And types are related to performance because they may be operated on different sets of CPU registers. In the case of floating point, a CPU need not have floating registers at all. So, we don't want types slip from under our grasp because the compiler decided to help the programmer. (One may think that all common CPUs have FP processing units today but it may not be the case in the future. For example, the not-yet-shipping Mill CPU can be configured to have zero or more processing units of any kind.) And we haven't talked about what type 14/7 should be. If we want that to be int, then I think we're in bigger trouble. (I think a timing values should be shorter than 22/7 and suddenly I get an int in my hand.) And only after writing that last sentence I realize that perhaps you meant this only for literals. If so, having same rules for literals vs. variables is beneficial and very important. There are known problems with C, C++, and D compilers' choosing finer precision during compile time for floating point literals during macro expansions. For example, calculations end up having different results on different compilations. Languages like Python 3+ can afford all of this because types or performance don't play a strong role in that environment. ;) Ali
Re: writeln double precision
On Tuesday, 24 October 2017 at 16:18:03 UTC, H. S. Teoh wrote: I have never seen a programming language in which dividing two integers yields a float or double. Either numbers default to a floating point type, in which case you begin with floats in the first place, or division is integer division, yielding an integer result. T Haven't used Python 3+?
Re: writeln double precision
On Tuesday, 24 October 2017 at 16:18:03 UTC, H. S. Teoh wrote: On Tue, Oct 24, 2017 at 10:02:11AM +, Arun Chandrasekaran via Digitalmars-d-learn wrote: On Monday, 23 October 2017 at 18:08:43 UTC, Ali Çehreli wrote: > On 10/23/2017 07:22 AM, Arun Chandrasekaran wrote: > > [...] > The rule is that every expression has a type and 22/7 is int. Thanks Ali. Is this for backward compatibility with C? Because, if there is a division, a natural/mathematical (not programmatic) expectation is to see a a double in the result. [...] I have never seen a programming language in which dividing two integers yields a float or double. Either numbers default to a floating point type, in which case you begin with floats in the first place, or division is integer division, yielding an integer result. T I'm not denying that all the programming languages does it this way (even if it is a cause of related bugs). I'm just questioning the reasoning behind why D does it this way and if it is for compatibility or if there is any other reasoning behind the decision. Arun
Re: writeln double precision
On Tue, Oct 24, 2017 at 10:02:11AM +, Arun Chandrasekaran via Digitalmars-d-learn wrote: > On Monday, 23 October 2017 at 18:08:43 UTC, Ali Çehreli wrote: > > On 10/23/2017 07:22 AM, Arun Chandrasekaran wrote: > > > [...] > > The rule is that every expression has a type and 22/7 is int. > > Thanks Ali. Is this for backward compatibility with C? Because, if > there is a division, a natural/mathematical (not programmatic) > expectation is to see a a double in the result. [...] I have never seen a programming language in which dividing two integers yields a float or double. Either numbers default to a floating point type, in which case you begin with floats in the first place, or division is integer division, yielding an integer result. T -- Real Programmers use "cat > a.out".
Re: Disabled and enabled copy constructors and .dup
On Tuesday, 24 October 2017 at 11:37:42 UTC, Per Nordlöw wrote: On Tuesday, 24 October 2017 at 07:56:34 UTC, Biotronic wrote: struct SuppressPostblit(T) { // Disguise T as a humble array. private ubyte[T.sizeof] _payload; ... A bit too hackish for my taste, but does the job still. Thanks. Cleaned up and slightly less hackish (yeah, it bothered me too): enum SuppressOptions { destructor = 1, postblit = 2 } struct Suppress(T, SuppressOptions options) if (options != 0) { import std.traits : isCopyable; private enum suppressPostblit = (options & SuppressOptions.postblit) != 0; private enum suppressDestructor = (options & SuppressOptions.destructor) != 0; private enum postblitName = __traits(hasMember, T, "__xpostblit") ? "__xpostblit" : "__postblit"; // Disguise T as a humble array. private ubyte[T.sizeof] _payload; // Create from instance of T. this(T arg) { _payload = *cast(ubyte[T.sizeof]*)&arg; } // Or forward constructor arguments to T's constructor. static if (__traits(hasMember, T, "__ctor")) { this(Args...)(Args args) if (__traits(compiles, (Args e){__traits(getMember, T.init, "__ctor")(e);})) { __traits(getMember, get, "__ctor")(args); } } // Call dtor static if (!suppressDestructor) { ~this() { destroy(get); } } // Call postblit static if (!suppressPostblit) { static if (!isCopyable!T) { @disable this(this); } else static if (__traits(hasMember, T, postblitName)) { this(this) { __traits(getMember, get, postblitName)(); } } } // Pretend to be a T. @property ref T get() { return *cast(T*)_payload.ptr; } alias get this; } struct S1 { @disable this(this); ~this() { throw new Exception("Don't touch my destructor!"); } } unittest { import std.exception; static assert(!__traits(compiles, (Suppress!S1 a) { auto b = a; })); static assert(__traits(compiles, (Suppress!(S1, SuppressOptions.postblit) a) { auto b = a; })); assertThrown({ Suppress!(S1, SuppressOptions.postblit) a; }()); assertNotThrown({ Suppress!(S1, SuppressOptions.postblit | SuppressOptions.destructor) a; }()); } -- Biotronic
Re: Disabled and enabled copy constructors and .dup
On Tuesday, 24 October 2017 at 07:56:34 UTC, Biotronic wrote: struct SuppressPostblit(T) { // Disguise T as a humble array. private ubyte[T.sizeof] _payload; ... A bit too hackish for my taste, but does the job still. Thanks.
Re: writeln double precision
On Monday, 23 October 2017 at 18:08:43 UTC, Ali Çehreli wrote: On 10/23/2017 07:22 AM, Arun Chandrasekaran wrote: > [...] The rule is that every expression has a type and 22/7 is int. Thanks Ali. Is this for backward compatibility with C? Because, if there is a division, a natural/mathematical (not programmatic) expectation is to see a a double in the result. Arun
Re: Disabled and enabled copy constructors and .dup
On Tuesday, 24 October 2017 at 07:33:43 UTC, Per Nordlöw wrote: If I have a `struct X` (container in my case) with disabled copying (postblit) and instead a .dup property, is it somehow possible, unsafe or not, to have `X` as a member of another `struct Y` with an enabled copy constructor which calls `X.dup`? With the same approach outline in https://forum.dlang.org/post/nakguitssvjdclpgw...@forum.dlang.org, it is indeed possible. In fact, simply using SuppressGC!X should enable it. Note however, that since the point of SuppressGC is to not call the object's destructor (and thus its name is poorly chosen by yours truly), you will need to do so explicitly. Updating the approach to only suppress postblits: struct SuppressPostblit(T) { // Disguise T as a humble array. private ubyte[T.sizeof] _payload; // Create from instance of T. this(T arg) { _payload = *cast(ubyte[T.sizeof]*)&arg; } // Or forward constructor arguments to T's constructor. static if (__traits(hasMember, T, "__ctor")) { this(Args...)(Args args) if (__traits(compiles, (Args e){__traits(getMember, T.init, "__ctor")(e);})) { __traits(getMember, get, "__ctor")(args); } } // Pretend to be a T. @property ref T get() { return *cast(T*)_payload.ptr; } alias get this; static if (__traits(hasMember, T, "__dtor")) { ~this() { __traits(getMember, get, "__dtor")(); } } } -- Simen
Disabled and enabled copy constructors and .dup
If I have a `struct X` (container in my case) with disabled copying (postblit) and instead a .dup property, is it somehow possible, unsafe or not, to have `X` as a member of another `struct Y` with an enabled copy constructor which calls `X.dup`?