Converting a string[] to char**

ag0aep6g via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon May 8 22:38:24 PDT 2017


On 05/09/2017 06:22 AM, David Zhang wrote:
> I'm playing around with Vulkan, and part of its initialization code
> calls for an array of strings as char**. I've tried casting directly
> (cast(char**)) and breaking it down into an array of char*s (char*[])
> before getting the pointer to its first element (&a[0]). It provides the
> correct type, but Vulkan rejects it. Is there a standard way of doing this?
>
> I'm trying to set the ppEnabledExtensionNames member of
> VkInstanceCreateInfo.

`string[]` isn't compatible with what's expected from the `char**`. The 
function expects to get a bunch of `char*`s, tightly packed. A 
`string[]` isn't that. A single `string` is a pointer-and-length pair. 
So a `string[]` has pointers and lengths alternating in memory.

Casting from `string[]` to `char*[]` means reinterpreting string lengths 
as pointers. That's not what you want. When dereferencing those fake 
pointers, you'll get garbage values or crash the program.

You have to create a new array of pointers. As rikki cattermole has 
pointed out, you also have to null-terminate the individual strings, and 
pass the amount of pointers in a separate parameter.

----
import std.algorithm.iteration: map;
import std.array: array;
import std.conv: to;
import std.string: toStringz;

string[] strs = ["foo", "bar", "baz"];

/* convert string[] to char*[]: */
immutable(char)*[] chptrs = strs.map!toStringz.array;

immutable(char)** ppEnabledLayerNames = chptrs.ptr;
uint enabledLayerCount = chptrs.length.to!uint;
----


More information about the Digitalmars-d-learn mailing list