Re: where is the memory corruption?

2020-12-10 Thread Виталий Фадеев via Digitalmars-d-learn

On Wednesday, 9 December 2020 at 20:35:21 UTC, Jack wrote:
I'm on linux/opensuse, trying to pass a wchar_* from C to D but 
I'm getting only the first letter of that string. Could someone 
help figure out why?


[...]



May be this help to you:

auto s2 = to!string(s);
to
auto s2 = fromWChar( s );

wstring fromWChar( const wchar* s )
{
import std.conv : to;
return s[ 0 .. wcslen( s ) ].to!wstring;
}


Example: https://run.dlang.io/is/PkCeTZ


Re: where is the memory corruption?

2020-12-10 Thread Patrick Schluter via Digitalmars-d-learn

On Wednesday, 9 December 2020 at 21:28:04 UTC, Paul Backus wrote:

On Wednesday, 9 December 2020 at 21:21:58 UTC, ag0aep6g wrote:


D's wchar is not C's wchar_t. D's wchar is 16 bits wide. The 
width of C's wchar_t is implementation-defined. In your case 
it's probably 32 bits.


In D, C's wchar_t is available as `core.stdc.stddef.wchar_t`.

http://dpldocs.info/experimental-docs/core.stdc.stddef.wchar_t.1.html


Don't use wchar_t in C. It has variable size depending of 
implementation. On Posix machines (Linux, BSD etc.) it's 32 bit 
wide UTF-32, on Windows it 16 bit UTF-16.





Re: where is the memory corruption?

2020-12-09 Thread Paul Backus via Digitalmars-d-learn

On Wednesday, 9 December 2020 at 21:21:58 UTC, ag0aep6g wrote:


D's wchar is not C's wchar_t. D's wchar is 16 bits wide. The 
width of C's wchar_t is implementation-defined. In your case 
it's probably 32 bits.


In D, C's wchar_t is available as `core.stdc.stddef.wchar_t`.

http://dpldocs.info/experimental-docs/core.stdc.stddef.wchar_t.1.html


Re: where is the memory corruption?

2020-12-09 Thread ag0aep6g via Digitalmars-d-learn

On 09.12.20 21:35, Jack wrote:
I'm on linux/opensuse, trying to pass a wchar_* from C to D but I'm 
getting only the first letter of that string. Could someone help figure 
out why?


this is the piece of D code:

extern(C) export
void sayHello(const (wchar) *s)

[...]
and below the piece of C code where I call the lib's function, compiled 
with clang -std=c11 -m64 dll.c -ldl

[...]

   const wchar_t *s2 = L"hello!";
   void (*fp)(const wchar_t*) = dlsym(lh, "sayHello");
   char *de = dlerror();
   if(de) {
     fprintf(stderr, "slsym error:%s\n", de);
     return EXIT_FAILURE;
   }
   fp(s2);

the output is "h" rather "hello". What am I missing?


D's wchar is not C's wchar_t. D's wchar is 16 bits wide. The width of 
C's wchar_t is implementation-defined. In your case it's probably 32 bits.


Because of that size mismatch, sayHello sees your L"hello!" string as 
"h\0e\0l\0l\0o\0!\0"w. And the conversion correctly stops at the first 
null character.


My C isn't very good, but I think char_16t is the correct analog to D's 
wchar. https://en.cppreference.com/w/c/string/multibyte/char16_t


Re: where is the memory corruption?

2020-12-09 Thread Dukc via Digitalmars-d-learn

On Wednesday, 9 December 2020 at 20:35:21 UTC, Jack wrote:

the output is "h" rather "hello". What am I missing?


In the sayHello function, you are converting a pointer to utf16 
character into utf8 string, not utf16 string to utf8 string. 
Convert the C wstring to a D `wstring` first 
(std.string.fromStringz).




where is the memory corruption?

2020-12-09 Thread Jack via Digitalmars-d-learn
I'm on linux/opensuse, trying to pass a wchar_* from C to D but 
I'm getting only the first letter of that string. Could someone 
help figure out why?


this is the piece of D code:

extern(C) export
void sayHello(const (wchar) *s)
{
import std.stdio : writeln;
import std.conv : to;

import core.runtime : rt_init, rt_term;
rt_init();
scope(exit) rt_term();

writeln("+sayHello()");
auto s2 = to!string(s);
writeln("s2 = ", s2);
writeln("-sayHello()");
}

build with dub, using "targetType": "dynamicLibrary" in dub.json.

and below the piece of C code where I call the lib's function, 
compiled with clang -std=c11 -m64 dll.c -ldl



  const char *libpath = "path/to/library.so";
  void *lh = dlopen(libpath, RTLD_LAZY);
  if(!lh) {
fprintf(stderr, "dlopen error: %s\n", dlerror());
return EXIT_FAILURE;
  }

  const wchar_t *s2 = L"hello!";
  void (*fp)(const wchar_t*) = dlsym(lh, "sayHello");
  char *de = dlerror();
  if(de) {
fprintf(stderr, "slsym error:%s\n", de);
return EXIT_FAILURE;
  }
  fp(s2);

the output is "h" rather "hello". What am I missing?