D struct with String type accessing from Python

cc cc at nevernet.com
Tue Dec 27 06:42:19 UTC 2022


On Monday, 26 December 2022 at 16:44:37 UTC, Ali Çehreli wrote:
> In any case, I have a presentation "Exposing a D Library to 
> Python Through a C API", which touches up on these topics:

I found the problem I was running into before.  Why does 
returning a struct, or sending a D string via an out parameter, 
work here, but simply returning a D string does not?

D DLL
```d
static struct DString {
	size_t length;
	immutable(char)* ptr;
	this(string str) {
		length = str.length;
		ptr = str.ptr;
	}
	void opAssign(string str) {
		length = str.length;
		ptr = str.ptr;
	}
}

static this() {
	cache = null; // DLL memory error if not initialized here
}
string[string] cache;

export string MyDLL_testStringReturn() {
	string s = "hello";
	cache.require(s);
	writefln("[D] pass: %s", s);
	return s;
}
export DString MyDLL_testStringReturnStruct() {
	string s = "hello";
	cache.require(s);
	auto dstr = DString(s);
	writefln("[D] pass: %s", dstr);
	return dstr;
}
export void MyDLL_testStringOut(out string str) {
	string s = "hello";
	cache.require(s);
	str = s;
	writefln("[D] pass: %s", str);
}
```

C# Main
```C#
[StructLayout(LayoutKind.Sequential, Size=16, Pack=1)]
public struct DString {
	public ulong length;
	public IntPtr ptr;
	public string str {
		get {
			byte[] b = new byte[length];
			for (int i = 0; i < (int)length; i++) {
				b[i] = Marshal.ReadByte(ptr, i);
			}
			return Encoding.UTF8.GetString(b);
		}
	}
}

[DllImport("mydll.dll")]
private static extern DString MyDLL_testStringReturn();
[DllImport("mydll.dll")]
private static extern DString MyDLL_testStringReturnStruct();
[DllImport("mydll.dll")]
private static extern void MyDLL_testStringOut(out DString dd);

public static void testString() {
	System.Console.WriteLine("Test [RETURN D string]");
	DString d1 = MyDLL_testStringReturn();
	System.Console.WriteLine("ok");
	System.Console.WriteLine("len: {0}", d1.length);
	System.Console.WriteLine("d1: {0}", d1.str);

	System.Console.WriteLine("Test [RETURN D struct]");
	DString d2 = MyDLL_testStringReturnStruct();
	System.Console.WriteLine("ok");
	System.Console.WriteLine("len: {0}", d2.length);
	System.Console.WriteLine("d2: {0}", d2.str);

	System.Console.WriteLine("Test [OUT D string]");
	DString d3;
	MyDLL_testStringOut(out d3);
	System.Console.WriteLine("ok");
	System.Console.WriteLine("len: {0}", d3.length);
	System.Console.WriteLine("d3: {0}", d3.str);
}
```

Output
```
Test [RETURN D string]
[D] pass: hello
ok
len: 0         !! Should be 5!
d1:            !! Should be hello!
Test [RETURN D struct]
[D] pass: DString(5, 7FFA497BCDD0)
ok
len: 5
d2: hello
Test [OUT D string]
[D] pass: hello
ok
len: 5
d3: hello
```


More information about the Digitalmars-d mailing list