D struct with String type accessing from Python

cc cc at nevernet.com
Tue Dec 27 18:31:34 UTC 2022


On Tuesday, 27 December 2022 at 17:04:03 UTC, Ali Çehreli wrote:
> I don't know C# to be sure but it must be ABI related. The way 
> D passes returned objects must be different from what C# 
> expects. (There is no extern(C#) to rely on here. ;) )

No need for extern(C#), extern(C) should be sufficient.  However, 
how does D pass a D slice as a return value under extern(C)?  
Does it just return nothing at all?  Returning a struct that is 
the same size as a D slice and memcpy'd from one works.

Here it is under C instead:

C
```c
#include <stdio.h>
#pragma comment(lib, "mydll.lib")
struct DString {
	unsigned __int64 len;
	char *ptr;
};
extern __declspec(dllimport) struct DString __cdecl 
MyDLL_testStringReturn(void);

int main(int argc, char** argv) {
	printf("[CMain] START\n");
	struct DString d = MyDLL_testStringReturn();
	printf("[CMain] len: %I64u\n", d.len);
	printf("[CMain] str: ");
	for (int i = 0; i < d.len; i++) {
		printf("%c", d.ptr[i]);
	}
	printf("\n");
	printf("[CMain] END\n");
}
```

This doesn't work (D):
```d
export auto MyDLL_testStringReturn() {
	string s = "hello";
	return s;
}
```
```
Segmentation fault
```

But this does (D):
```d
export auto MyDLL_testStringReturn() {
	import core.stdc.string : memcpy;
	string s = "hello";
	static struct N {
		ubyte[string.sizeof] b;
	}
	static assert(N.sizeof == string.sizeof);
	N n;
	memcpy(&n, &s, string.sizeof);
	return n;
}
```
```
[CMain] START
[CMain] len: 5
[CMain] str: hello
[CMain] END
```



More information about the Digitalmars-d mailing list