Search code examples
zig

error: parameter of type '[]const u8' not allowed in function with calling convention 'C'


I wrote the below as a simple lib that is reading .env:

// src/lib/env.zig
const std = @import("std");

/// The getValue function is returning the value of the provided key.
/// The `.env` file should be located at the root folder.
pub fn getValue(key: []const u8) !?[]const u8 {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    // const allocator = std.heap.page_allocator;
    // _ = allocator;
    defer if (gpa.deinit() != .ok) {
        std.log.err("oh no, we've got a leak", .{});
    } else {
        std.log.debug("memory managed correctly", .{});
    };

    const file = try std.fs.cwd().openFile(".env", .{});
    defer file.close();

    var buf: [1024]u8 = undefined;
    var stream = file.reader();

    while (try stream.readUntilDelimiterOrEof(&buf, 10)) |line| {
        var key_value = std.mem.split(u8, line, "=");
        const env_key = key_value.next() orelse "";
        const value = key_value.next() orelse "";
        if (std.mem.eql(u8, env_key, key)) {
            std.debug.print("Value of of {s} is: {s}\n", .{ key, value });
            return value;
        }
    }
    return null;
}

And was able to call it from the main function as:

// src/main.zig
const std = @import("std");
const lib = @import("./lib/env.zig");

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    const allocator = gpa.allocator();
    _ = allocator;
    defer if (gpa.deinit() != .ok) {
        std.log.err("oh no, we've got a leak", .{});
    } else {
        std.log.debug("memory managed correctly", .{});
    };

    const key = "my-api";
    const value = try lib.getValue(key);
    if (value) |v| {
        std.debug.print("Value of {s}: {s}\n", .{ key, v });
    } else {
        std.debug.print("Key {s} not found\n", .{key});
    }
}

Then I tried to build a binary file from this lib, but got the below error:

src/main.zig:3:51: error: parameter of type '[]const u8' not allowed in function with calling convention 'C'
export fn getValue(key: []const u8) !?[]const u8 {
                   ^~~~~~~~~~~~~~~

I read this, but did not get how to make the interface for a pointer or string: https://ziglearn.org/chapter-4/


Solution

  • There seems to be something wrong with your assumptions. You call it a "library", but I don't see you building it as a DLL/library and dynamically loading it into your program. Instead, you just import it as a regular Zig file. No export is needed in this case, just pub.