digitalmars.D.learn - where is the memory corruption?
- Jack (35/35) Dec 09 2020 I'm on linux/opensuse, trying to pass a wchar_* from C to D but
- Dukc (5/6) Dec 09 2020 In the sayHello function, you are converting a pointer to utf16
- ag0aep6g (10/30) Dec 09 2020 [...]
- Paul Backus (3/6) Dec 09 2020 In D, C's wchar_t is available as `core.stdc.stddef.wchar_t`.
- Patrick Schluter (4/11) Dec 10 2020 Don't use wchar_t in C. It has variable size depending of
- =?UTF-8?B?0JLQuNGC0LDQu9C40Lkg0KTQsNC0?= =?UTF-8?B?0LXQtdCy?= (11/15) Dec 10 2020 May be this help to you:
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?
Dec 09 2020
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).
Dec 09 2020
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
Dec 09 2020
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
Dec 09 2020
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: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.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
Dec 10 2020
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
Dec 10 2020