Re: exporting function from betterc to windows dll

2020-03-14 Thread Mike Parker via Digitalmars-d-learn

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?

2020-03-14 Thread Marcone via Digitalmars-d-learn

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?

2020-03-14 Thread Adam D. Ruppe via Digitalmars-d-learn

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

2020-03-14 Thread User via Digitalmars-d-learn

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?

2020-03-14 Thread H. S. Teoh via Digitalmars-d-learn
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")?

2020-03-14 Thread Adnan via Digitalmars-d-learn

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")?

2020-03-14 Thread Adnan via Digitalmars-d-learn

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")?

2020-03-14 Thread Adam D. Ruppe via Digitalmars-d-learn

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")?

2020-03-14 Thread Adnan via Digitalmars-d-learn

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?

2020-03-14 Thread 12345swordy via Digitalmars-d-learn

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")?

2020-03-14 Thread Adnan via Digitalmars-d-learn
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?

2020-03-14 Thread Adnan via Digitalmars-d-learn
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?

2020-03-14 Thread aliak via Digitalmars-d-learn

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?

2020-03-14 Thread Luhrel via Digitalmars-d-learn

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

2020-03-14 Thread Abby via Digitalmars-d-learn
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?

2020-03-14 Thread 12345swordy via Digitalmars-d-learn

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 ?

2020-03-14 Thread wjoe via Digitalmars-d-learn
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

2020-03-14 Thread Calvin P via Digitalmars-d-learn

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

=