What exactly gets returned with extern(C) export string func() ?

cc cc at nevernet.com
Sun Jun 13 10:02:45 UTC 2021


D under dmd/Win10/64-bit currently seems to store strings 
(slices) internally like so:
```d
static struct DString {
	size_t length;
	immutable(char)* ptr;
}
static assert(DString.sizeof == string.sizeof);
string s = "abcde";
DString d;
memcpy(&d, &s, s.sizeof);
assert(d.length == s.length);
assert(d.ptr == s.ptr);
```

If I write a DLL export like:
```d
extern(C) export string someDLLFunc() {
	return "hello";
}
```
and import it in C# (VS .NET):
```c#
struct DString {
	public long length;
	public IntPtr ptr;
}
[DllImport("mydll.dll")]
extern DString someDLLFunc();
...
DString d = someDLLFunc();
System.Console.WriteLine("dstr: {0} : {1}", d.length, d.ptr);
```
Though C# seems to properly be getting 16 bytes as the return 
value from `someDLLFunc()`, the length and ptr parameters are 
both 0.

If I explicitly pass a struct back from D instead like so:
```d
static struct DString {
	size_t length;
	immutable(char)* ptr;
	this(string str) {
		length = str.length;
		ptr = str.ptr;
	}
}
extern(C) export DString someDLLFunc() {
	return DString("hello");
}
```
it seems to work as expected with the same C# code.  Does D 
explicitly disallow slices as an extern(C) export parameter type?


More information about the Digitalmars-d-learn mailing list