Re: exporting function from betterc to windows dll
On Saturday, 14 March 2020 at 20:53:45 UTC, Abby wrote: I would like to export some functions from my bettec dll for dotnet core application in windows. Right now I have compiled dll using dmd v2.091.0-dirty simply by ´dub build´ this is the function I have extern(C) char* test_echo(const(char)* line, size_t len, ref size_t resLen) { enum format = "{\"message\": \"%s\"}\n"; auto response = cast(char*)malloc(format.length + len); resLen = sprintf(response, format, line); return response; } and this is my dotnet core equivalent [DllImport(DllName, CallingConvention = CallingConvention.StdCall)] static extern IntPtr test_echo([MarshalAs(UnmanagedType.LPStr)]string line, ulong len, out ulong resLen); This works for me in linux but does not in windows, any idea what I'm doing wrong? For one thing, you're defining it with stdcall in dotnet, but cdecl in the code. You should change the convention on the dotnet side to CallingConvention.Cdecl. Or, if you really want to use stdcall, use extern(System) in D -- the equivalent of extern(Windows) on Windows and extern(C) everywhere else. Also, I would expect you'd have to use export [1] on the D side for the symbol to be loadable from the dll: extern(C) export char* test_echo(...) { ... } This should be the equivalent of __declspec(dllexport) for C and C++ on Windows. [1] https://dlang.org/spec/attribute.html#visibility_attributes (Item #7)
How catch any error in Dlang like Python try-except?
How catch any error in Dlang like Python tray-except? It is very useful when making tests. But only who came from interpreted languages can understand. Exemple: import std; void main() { try { writelnX("try function that not exist"); } catch (Throwable e) { writeln("Error: %s".format(e.msg)); } }
Re: How catch any error in Dlang like Python try-except?
On Sunday, 15 March 2020 at 02:11:21 UTC, Marcone wrote: It is very useful when making tests. But only who came from interpreted languages can understand. The compiler catches all compile errors. It is impossible to even run a program if there is even a single compile error. Thus they cannot be caught.
Re: exporting function from betterc to windows dll
On Saturday, 14 March 2020 at 20:53:45 UTC, Abby wrote: I would like to export some functions from my bettec dll for dotnet core application in windows. [...] It is the calling convention.
Re: How does one read file line by line / upto a specific delimeter of an MmFile?
On Sat, Mar 14, 2020 at 10:37:37PM +, Adnan via Digitalmars-d-learn wrote: > https://dlang.org/library/std/mmfile/mm_file.html doesn't seem to > specify anything similar to lines() or byLine() or byLineCopy() etc. That's because a memory-mapped file appears directly in your program's memory address space as if it was an array of bytes (ubyte[]). No interpretation is imposed upon the contents. If you want lines out of it, try casting the memory to const(char)[] and using std.algorithm.splitter to get a range of lines. For example: auto mmfile = new MmFile("myfile.txt"); auto data = cast(const(char)[]) mmfile[]; auto lines = data.splitter("\n"); foreach (line; lines) { ... } T -- "You are a very disagreeable person." "NO."
Re: Why can't the compiler properly detect the type of Array!string("something")?
On Sunday, 15 March 2020 at 00:04:09 UTC, Adnan wrote: On Saturday, 14 March 2020 at 23:54:44 UTC, Adam D. Ruppe wrote: On Saturday, 14 March 2020 at 23:39:11 UTC, Adnan wrote: Full code this worked for me when i copy/pasted it... are you sure that has the error? if so what compiler version you on? This is indeed very strange, godbolt says it's alright: https://d.godbolt.org/z/DaaPxX Now my compiler version: $ dmd --version && ldc2 --version DMD64 D Compiler v2.090.0 Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved written by Walter Bright LDC - the LLVM D compiler (1.18.0): based on DMD v2.088.1 and LLVM 9.0.0 built with LDC - the LLVM D compiler (1.18.0) Default target: x86_64-unknown-linux-gnu Host CPU: znver1 http://dlang.org - http://wiki.dlang.org/LDC Registered Targets: aarch64- AArch64 (little endian) aarch64_32 - AArch64 (little endian ILP32) aarch64_be - AArch64 (big endian) arm- ARM arm64 - ARM64 (little endian) arm64_32 - ARM64 (little endian ILP32) armeb - ARM (big endian) mips - MIPS (32-bit big endian) mips64 - MIPS (64-bit big endian) mips64el - MIPS (64-bit little endian) mipsel - MIPS (32-bit little endian) msp430 - MSP430 [experimental] nvptx - NVIDIA PTX 32-bit nvptx64- NVIDIA PTX 64-bit ppc32 - PowerPC 32 ppc64 - PowerPC 64 ppc64le- PowerPC 64 LE riscv32- 32-bit RISC-V riscv64- 64-bit RISC-V thumb - Thumb thumbeb- Thumb (big endian) wasm32 - WebAssembly 32-bit wasm64 - WebAssembly 64-bit x86- 32-bit X86: Pentium-Pro and above x86-64 - 64-bit X86: EM64T and AMD64 Note that both ldc2 and dmd has the same complain d$ dmd --version && cat source/app.d && dub build DMD64 D Compiler v2.090.0 Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved written by Walter Bright string smallestRepr(const string arg) { auto repeated = arg ~ arg; string result = arg; foreach (i; 1 .. arg.length) { const slice = repeated[i .. i + arg.length]; if (slice < result) result = slice; } return result; } unittest { assert("cba".smallestRepr() == "acb"); } void main(const string[] args) { import std.stdio : write, File; import std.container : Array; Array!string[string] wordTable; foreach (string word; File(args[1]).byLineCopy()) { word = word[0 .. $ - 1]; // strip the newline character const string key = word.smallestRepr(); debug { if (key in wordTable) wordTable[key] ~= word; else wordTable[key] = Array!string(word); } else { wordTable.require(key, Array!string()) ~= word; } } foreach (array; wordTable.values) { if (array.length == 4) { foreach (word; array) { write(word, ", "); } write("\n"); break; } } } Performing "debug" build using dmd for x86_64. dbed ~master: building configuration "application"... source/app.d(29,34): Error: template std.container.array.Array!string.Array.__ctor cannot deduce function from argument types !()(string), candidates are: /snap/dmd/99/bin/../import/phobos/std/container/array.d(467,5): __ctor(U)(U[] values...) with U = immutable(char) must satisfy the following constraint: isImplicitlyConvertible!(U, T) /snap/dmd/99/bin/../import/phobos/std/container/array.d(501,5): __ctor(Range)(Range r) with Range = string must satisfy the following constraint: isImplicitlyConvertible!(ElementType!Range, T) source/app.d(36,2): Warning: statement is not reachable dmd failed with exit code 1.
Re: Why can't the compiler properly detect the type of Array!string("something")?
On Saturday, 14 March 2020 at 23:54:44 UTC, Adam D. Ruppe wrote: On Saturday, 14 March 2020 at 23:39:11 UTC, Adnan wrote: Full code this worked for me when i copy/pasted it... are you sure that has the error? if so what compiler version you on? This is indeed very strange, godbolt says it's alright: https://d.godbolt.org/z/DaaPxX Now my compiler version: $ dmd --version && ldc2 --version DMD64 D Compiler v2.090.0 Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved written by Walter Bright LDC - the LLVM D compiler (1.18.0): based on DMD v2.088.1 and LLVM 9.0.0 built with LDC - the LLVM D compiler (1.18.0) Default target: x86_64-unknown-linux-gnu Host CPU: znver1 http://dlang.org - http://wiki.dlang.org/LDC Registered Targets: aarch64- AArch64 (little endian) aarch64_32 - AArch64 (little endian ILP32) aarch64_be - AArch64 (big endian) arm- ARM arm64 - ARM64 (little endian) arm64_32 - ARM64 (little endian ILP32) armeb - ARM (big endian) mips - MIPS (32-bit big endian) mips64 - MIPS (64-bit big endian) mips64el - MIPS (64-bit little endian) mipsel - MIPS (32-bit little endian) msp430 - MSP430 [experimental] nvptx - NVIDIA PTX 32-bit nvptx64- NVIDIA PTX 64-bit ppc32 - PowerPC 32 ppc64 - PowerPC 64 ppc64le- PowerPC 64 LE riscv32- 32-bit RISC-V riscv64- 64-bit RISC-V thumb - Thumb thumbeb- Thumb (big endian) wasm32 - WebAssembly 32-bit wasm64 - WebAssembly 64-bit x86- 32-bit X86: Pentium-Pro and above x86-64 - 64-bit X86: EM64T and AMD64 Note that both ldc2 and dmd has the same complain
Re: Why can't the compiler properly detect the type of Array!string("something")?
On Saturday, 14 March 2020 at 23:39:11 UTC, Adnan wrote: Full code this worked for me when i copy/pasted it... are you sure that has the error? if so what compiler version you on?
Re: Why can't the compiler properly detect the type of Array!string("something")?
On Saturday, 14 March 2020 at 23:39:11 UTC, Adnan wrote: In the following code the compiler says the type is Array!()(string): if (key in wordTable) wordTable[key] ~= word; else wordTable[key] = Array!string(word); source/app.d(29,36): Error: template std.container.array.Array!string.Array.__ctor cannot deduce functi on from argument types !()(string), candidates are: /snap/dmd/99/bin/../import/phobos/std/container/array.d(467,5): __ctor(U)(U[] values...) with U = immutable(char) must satisfy the following constraint: isImplicitlyConvertible!(U, T) /snap/dmd/99/bin/../import/phobos/std/container/array.d(501,5): __ctor(Range)(Range r) with Range = string must satisfy the following constraint: isImplicitlyConvertible!(ElementType!Range, T) Full code string smallestRepr(const string arg) { auto repeated = arg ~ arg; string result = arg; foreach (i; 1 .. arg.length) { const slice = repeated[i .. i + arg.length]; if (slice < result) result = slice; } return result; } unittest { assert("cba".smallestRepr() == "acb"); } void main(const string[] args) { import std.stdio : write, File; import std.container : Array; Array!string[string] wordTable; foreach (string word; File(args[1]).byLineCopy()) { word = word[0 .. $ - 1]; // strip the newline character const string key = word.smallestRepr(); debug { if (key in wordTable) wordTable[key] ~= word; else wordTable[key] = Array!string(word); } else { wordTable.require(key, Array!string()) ~= word; } } foreach (array; wordTable.values) { if (array.length == 4) { foreach (word; array) { write(word, ", "); } write("\n"); break; } } }
Re: Pattern matching via switch?
On Saturday, 14 March 2020 at 20:52:30 UTC, aliak wrote: On Saturday, 14 March 2020 at 19:04:28 UTC, 12345swordy wrote: [...] You can use the sumtype package (https://code.dlang.org/packages/sumtype): [...] That simply to much verbiage.
Why can't the compiler properly detect the type of Array!string("something")?
In the following code the compiler says the type is Array!()(string): if (key in wordTable) wordTable[key] ~= word; else wordTable[key] = Array!string(word); source/app.d(29,36): Error: template std.container.array.Array!string.Array.__ctor cannot deduce functi on from argument types !()(string), candidates are: /snap/dmd/99/bin/../import/phobos/std/container/array.d(467,5): __ctor(U)(U[] values...) with U = immutable(char) must satisfy the following constraint: isImplicitlyConvertible!(U, T) /snap/dmd/99/bin/../import/phobos/std/container/array.d(501,5): __ctor(Range)(Range r) with Range = string must satisfy the following constraint: isImplicitlyConvertible!(ElementType!Range, T)
How does one read file line by line / upto a specific delimeter of an MmFile?
https://dlang.org/library/std/mmfile/mm_file.html doesn't seem to specify anything similar to lines() or byLine() or byLineCopy() etc.
Re: Pattern matching via switch?
On Saturday, 14 March 2020 at 19:04:28 UTC, 12345swordy wrote: I.E. switch (object) case Type1 t1: case Type2 t2: case Type3 t3: You can use the sumtype package (https://code.dlang.org/packages/sumtype): alias T = SumType!(Type1, Type2, Type3); T(object).match!( (Type1 t1) => "t1", (Type2 t2) => "t2", (Type3 t3) => "t3", ); Or you can make a quick template like: template switch_(funs...) { auto switch_(T)(auto ref T t) { static foreach (fun; funs) { static if (is(typeof(fun(T.init { return fun(t); } } } } struct A {} struct B {} struct C {} void main() { auto a = C(); a.switch_!( (A _) => "a", (B _) => "b", (C _) => "c", ).writeln; } The template above is a quick fix and will have some holes though. Off the top of my head if more than one lambda "fits" there'll be problems.
Re: Pattern matching via switch?
On Saturday, 14 March 2020 at 19:04:28 UTC, 12345swordy wrote: I.E. switch (object) case Type1 t1: case Type2 t2: case Type3 t3: As far as I know, there's no way to do that in a switch. However, you can do something like this: --- void main() { auto i = new Type1(); foo(i); } void foo(T)(T type) { static if (is(T == Type1)) { // ... } else static if (is(T == Type2)) { // ... } // ... } --- Hope this helps
exporting function from betterc to windows dll
I would like to export some functions from my bettec dll for dotnet core application in windows. Right now I have compiled dll using dmd v2.091.0-dirty simply by ´dub build´ this is the function I have extern(C) char* test_echo(const(char)* line, size_t len, ref size_t resLen) { enum format = "{\"message\": \"%s\"}\n"; auto response = cast(char*)malloc(format.length + len); resLen = sprintf(response, format, line); return response; } and this is my dotnet core equivalent [DllImport(DllName, CallingConvention = CallingConvention.StdCall)] static extern IntPtr test_echo([MarshalAs(UnmanagedType.LPStr)]string line, ulong len, out ulong resLen); This works for me in linux but does not in windows, any idea what I'm doing wrong? This is the output from dotnet core Unhandled exception. System.EntryPointNotFoundException: Unable to find an entry point named 'test_echo' in DLL 'test.dll'
Pattern matching via switch?
I.E. switch (object) case Type1 t1: case Type2 t2: case Type3 t3:
Re: Is it possible to dynamically load a @safe function from a shared library ?
On Friday, 13 March 2020 at 20:31:16 UTC, Steven Schveighoffer wrote: On 3/13/20 4:22 PM, wjoe wrote: I would expect that something could be written to turn a signature string into a mangling and also provide the correct type upon return. Something like: auto f = getFunction!(@safe void function(int))("package.module.symbol"); and have it properly mangle the expected function name and pull it from the dynamic library. -Steve Thanks for your reply. core.demangle: mangle; comes to mind. And in fact, because the exports weren't extern(C), that's how I imported the symbols; prior to reading H. S. Teoh's reply. That's when I realized that I've got a problem. Even though I know that the function being exported are all compiled @safe, that doesn't mean I can count on the fact. Since a plugin is a separate file it can be swapped out with a version that exports all the same (forged) symbols names but with a @system implementation. Forging these symbol names is as easy as something like mangle!(int function(int))("a.b")); (=_D1a1bPFiZi) and copy/pasting that into pragma(mangle, "_D1a1bPFiZi") and voila, the loader can nothing but trust that this is true. Forging is maybe too hard a word but my vocabulary lacks a better one.
need help to get member function const address
I use this code to get member function address on runtime: = struct A { this(){}; } auto ctor = (&__traits(getMember, A.init,"__ctor")).funcptr; = my question is, how to get it in compile time like static function address: = struct A { void d(){}; static void fn(){}; } enum FN = &A.fn; // static method address is ok enum A0 = &(A.d).funcptr; // Error: need this for d of type void() enum A1 = (&__traits(getMember, A,"d")).funcptr; // Error: no property funcptr for type void function() enum A2 = (&__traits(getMember, A.init,"d")).funcptr; // Error: (&A().d).funcptr cannot be evaluated at compile time =