# Using Zig to Call C Code: Strings

**URL:** <https://ziggit.dev/t/using-zig-to-call-c-code-strings/2470>\
**Category:** Media\
**Tags:** c, standard-library\
**Created:** [December 15, 2023, 2:14pm UTC](https://ziggit.dev/t/using-zig-to-call-c-code-strings/2470 "2023-12-15T14:14:28Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![mtlynch](https://ziggit.dev/user_avatar/ziggit.dev/mtlynch/32/1254_2.png) [@mtlynch](https://ziggit.dev/u/mtlynch)\
**Post date:** [December 15, 2023, 2:14pm UTC](https://ziggit.dev/t/using-zig-to-call-c-code-strings/2470/1 "2023-12-15T14:14:28Z")

</div>

I’m a Zig newcomer, and I had trouble finding detailed documentation about how to handle strings when calling C code from Zig.

I wrote this explanation of how strings differ between Zig and C and how to use Zig to write safer wrappers for C functions that take strings as input or output:

- [Using Zig to Call C Code: Strings](https://mtlynch.io/notes/zig-strings-call-c-code/)

I’m still a Zig beginner, so I appreciate any feedback about the post, especially regarding [the last example](https://mtlynch.io/notes/zig-strings-call-c-code/#improving-the-wrapper-with-zig-managed-buffers), whose behavior I don’t fully understand.

---

<div class="post-metadata">

**Author:** ![LucasSantos91](https://ziggit.dev/user_avatar/ziggit.dev/lucassantos91/32/440_2.png) [@LucasSantos91](https://ziggit.dev/u/LucasSantos91)\
**Post date:** [December 15, 2023, 4:07pm UTC](https://ziggit.dev/t/using-zig-to-call-c-code-strings/2470/2 "2023-12-15T16:07:12Z")

</div>

Cool write up.  
Regarding the last example, I don’t get why you’re calling the C code to duplicate the string, and then doing the same thing with zig functions. Just allocate a buffer and copy the contents of the string, no need for the C detour.

---

<div class="post-metadata">

**Author:** ![mtlynch](https://ziggit.dev/user_avatar/ziggit.dev/mtlynch/32/1254_2.png) [@mtlynch](https://ziggit.dev/u/mtlynch)\
**Post date:** [December 15, 2023, 4:11pm UTC](https://ziggit.dev/t/using-zig-to-call-c-code-strings/2470/3 "2023-12-15T16:11:03Z")

</div>

Thanks for reading!

> [@LucasSantos91](#):
>
> Regarding the last example, I don’t get why you’re calling the C code to duplicate the string, and then doing the same thing with zig functions. Just allocate a buffer and copy the contents of the string, no need for the C detour.

It’s admittedly a contrived example because there’s no reason to call `strdup` from Zig since Zig has better mechanisms for copying a string.

I’m using `strdup` just because it’s a simple example of how to manage a string in Zig when it’s the output of a C function.

---

<div class="post-metadata">

**Author:** ![efjimm](https://ziggit.dev/user_avatar/ziggit.dev/efjimm/32/5221_2.png) [@efjimm](https://ziggit.dev/u/efjimm)\
**Post date:** [December 16, 2023, 9:03pm UTC](https://ziggit.dev/t/using-zig-to-call-c-code-strings/2470/4 "2023-12-16T21:03:05Z")

</div>

Great article. Some notes:

From the language reference, the first line in the `C Pointers` section:

> This type is to be avoided whenever possible. The only valid reason for using a C pointer is in auto-generated code from translating C code.

The reason they exist is because auto-generated code can’t tell if a pointer translated from C should be a single item pointer or a many item pointer. C pointers coerce to single or many pointers, so for code where you know the intention of the pointer you should use the respective single or many pointer. By using C pointers you miss out on enforced null checking and automatic dereferencing using the `.` operator. You should change this

```zig
    const cCopy: [*c]u8 = cString.strdup(str);
    if (cCopy == null) {
        // Maybe we can return a better error by calling std.os.errno(), but for
        // now, return a generic error.
        return error.StrdupFailure;
    }

```

To this:

```zig
    const cCopy: [*:0]u8 = cString.strdup(str) orelse return error.OutOfMemory;

```

`strdup` can only fail with ENOMEM so I changed the error. What’s nice about Zig is that control flow statements _are_ expressions, so we can put a return on the right hand side of the `orelse` here.  
And just to note that the function `Allocator.dupeZ` exists which will copy a slice and append a null terminator if necessary - though using it kinda defeats the point of the last example.

> The downside of this revision is that it’s slower than the previous version. I’m allocating and copying memory twice: once in C, and another time in Zig. If this were performance-critical code, perhaps I’d take the speedup by making the caller deal with the C array, but in general, I prefer to let Zig manage my memory.

If you want the performance and to let the allocator manage the memory, you wouldn’t call `strdup` at all and just copy using the passed in allocator - the call to `strdup` is completely unnecessary in the last example.

---

<div class="post-metadata">

**Author:** ![mtlynch](https://ziggit.dev/user_avatar/ziggit.dev/mtlynch/32/1254_2.png) [@mtlynch](https://ziggit.dev/u/mtlynch)\
**Post date:** [December 16, 2023, 10:13pm UTC](https://ziggit.dev/t/using-zig-to-call-c-code-strings/2470/5 "2023-12-16T22:13:50Z")

</div>

Thanks, @efjimm! I’ve updated the post to integrate your suggestions.

> By using C pointers you miss out on enforced null checking and automatic dereferencing using the `.` operator. You should change this

Ah, cool! I didn’t understand that about C pointers. I thought they were automatically what you get back from C code, but now I understand that I have some control in a more specific type.

> And just to note that the function `Allocator.dupeZ` exists which will copy a slice and append a null terminator if necessary - though using it kinda defeats the point of the last example.

Oh, cool! I wasn’t aware of the `dupeZ` function. That’s simpler than what I was doing.

> If you want the performance and to let the allocator manage the memory, you wouldn’t call `strdup` at all and just copy using the passed in allocator - the call to `strdup` is completely unnecessary in the last example.

Right, I wish there was a better libc function to call to demonstrate the concept.

What the post is meant to demonstrate is “here’s what you would do with a C function that returns a C-allocated array.” I’m ignoring the particulars of what `strdup` achieves and focusing more on the fact that it allocates and returns a string from C.

Because, similarly, there’s no reason to call C’s `strlen` function on a Zig string because I can just check the `.len` property in `O(1)` time. But the idea is just to show how to pass a Zig string to a C function that takes a string input.

---

<div class="post-metadata">

**Author:** ![AndrewCodeDev](https://ziggit.dev/letter_avatar_proxy/v4/letter/a/278dde/32.png) [@AndrewCodeDev](https://ziggit.dev/u/AndrewCodeDev)\
**Post date:** [December 16, 2023, 11:31pm UTC](https://ziggit.dev/t/using-zig-to-call-c-code-strings/2470/6 "2023-12-16T23:31:33Z")

</div>

It’s hard to find non-trivial examples that also display nicely in a blog post. I think it’s great idea to have more material and examples about the C-interoperability aspect of Zig.
