# Error "expected type \`T\`, found \`T\`" with types imported from C headers

**URL:** <https://ziggit.dev/t/error-expected-type-t-found-t-with-types-imported-from-c-headers/12200>\
**Category:** Help\
**Tags:** c, zig-0-15-1\
**Created:** [September 25, 2025, 6:27am UTC](https://ziggit.dev/t/error-expected-type-t-found-t-with-types-imported-from-c-headers/12200 "2025-09-25T06:27:01Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![ubavic](https://ziggit.dev/user_avatar/ziggit.dev/ubavic/32/6430_2.png) [@ubavic](https://ziggit.dev/u/ubavic)\
**Post date:** [September 25, 2025, 6:27am UTC](https://ziggit.dev/t/error-expected-type-t-found-t-with-types-imported-from-c-headers/12200/1 "2025-09-25T06:27:02Z")

</div>

Hello,

I am migrating a [shared library (pkcs11 module)](https://github.com/ubavic/srb-id-pkcs11) to zig 0.15. I’ve hit an error that I can’t resolve. For some types imported from `.h` files, I get errors like the following

```zig
src/p11_object_management.zig:171:87: error: expected type '[]cimport.struct_CK_ATTRIBUTE', found '[]cimport.struct_CK_ATTRIBUTE'
        search_template = object.parseAttributes(current_session.allocator, template.?[0..count]) catch |err|
src/p11_object_management.zig:171:87: note: pointer type child 'cimport.struct_CK_ATTRIBUTE' cannot cast into pointer type child 'cimport.struct_CK_ATTRIBUTE'
.zig-cache/o/54dbc096318bceda383adc744f238447/cimport.zig:139:40: note: struct declared here (2 times)
pub const struct_CK_ATTRIBUTE = extern struct {
                                ~~~~~~~^~~~~~
src/object.zig:288:15: note: parameter type declared here
    template: []pkcs.CK_ATTRIBUTE,

```

I noticed this happens when the zig file where the function is called is different from the file where the function is defined. In both files, the C type is imported the same way, directly from the C header. I don’t import or use any C functions, only type definitions.

It also happens with zig structs that have fields using types imported from a C header:

```zig
src/certificate.zig:69:27: error: expected type 'cimport.struct_CK_DATE', found 'cimport.struct_CK_DATE'
        .start_date = pkcs.CK_DATE{},
.zig-cache/o/54dbc096318bceda383adc744f238447/cimport.zig:146:35: note: struct declared here (2 times)
pub const struct_CK_DATE = extern struct {

```

Function signatures also (in this case, types are different, but this error isn’t present on v0.14):

```zig
src/p11_general.zig:119:20: error: expected type '*const fn (c_ulong, [*c]cimport.struct_CK_SLOT_INFO) callconv(.c) c_ulong', found '*const fn (c_ulong, ?*cimport.struct_CK_SLOT_INFO) callconv(.c) c_ulong'
    .C_GetSlotInfo = p11_slot_and_token.C_GetSlotInfo,

```

Here is a minimal example that demonstrates this behavior:

```zig
// build.zig
const std = @import("std");

pub fn build(b: *std.Build) void {
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

    const mod = b.createModule(.{
        .target = target,
        .optimize = optimize,
        .root_source_file = b.path("src/p11_general.zig"),
        .link_libc = true,
    });

    const lib = b.addLibrary(.{
        .linkage = std.builtin.LinkMode.dynamic,
        .name = "srb-id-pkcs11",
        .root_module = mod,
    });

    lib.addIncludePath(b.path("include"));
    b.installArtifact(lib);
}

```

```zig
// src/p11_general.zig
const pkcs = @cImport({
    @cInclude("a.h");
});

const a = @import("a.zig");

pub export fn C_FindObjectsInit(
    template: ?[*]pkcs.CK_ATTRIBUTE,
    count: usize,
) void {
    a.parseAttributes(template.?[0..count]);
}

```

```zig
// a.zig
const pkcs = @cImport({
    @cInclude("a.h");
});

pub fn parseAttributes(
    _: []pkcs.CK_ATTRIBUTE,
) void {}

```

```C
// a.h
typedef struct CK_ATTRIBUTE {
  int type;
  void* pValue;
  int ulValueLen; 
} CK_ATTRIBUTE;

```

---

<div class="post-metadata">

**Author:** ![vulpesx](https://ziggit.dev/user_avatar/ziggit.dev/vulpesx/32/3989_2.png) [@vulpesx](https://ziggit.dev/u/vulpesx)\
**Post date:** [September 25, 2025, 7:49am UTC](https://ziggit.dev/t/error-expected-type-t-found-t-with-types-imported-from-c-headers/12200/2 "2025-09-25T07:49:15Z")

</div>

every c import is unique regardless of if they have the same content/args.

Ideally only have one in a project.

Obligatory, `@cImport/Include` is deprecated in favour of the build systems `addTranslateC` + normal `@import`.  
That is due to zig wanting to make llvm optional which includes clang that is used for c translation.

---

<div class="post-metadata">

**Author:** ![Sze](https://ziggit.dev/user_avatar/ziggit.dev/sze/32/496_2.png) [@Sze](https://ziggit.dev/u/Sze)\
**Post date:** [September 25, 2025, 2:25pm UTC](https://ziggit.dev/t/error-expected-type-t-found-t-with-types-imported-from-c-headers/12200/3 "2025-09-25T14:25:02Z")

</div>

To add a little bit of explanation to this:  
If you still use `@cImport` make sure that you only use it in one place, there you can declare it as a public declaration, then from the other place where you need it you can import and use that public declaration.

And if you change towards the [new way](https://ziggit.dev/t/addtranslatec-for-system-headers/9976/2) then the `addTranslateC` gives you a `*TranslateC` which you can call `add`-/`createModule` module on, the resulting module can be imported at multiple places just like regular modules.

One of the benefits of the new way is that this mistake is less likely to happen (unless you manually create multiple separate translate-c modules).

---

<div class="post-metadata">

**Author:** ![ubavic](https://ziggit.dev/user_avatar/ziggit.dev/ubavic/32/6430_2.png) [@ubavic](https://ziggit.dev/u/ubavic)\
**Post date:** [September 25, 2025, 5:20pm UTC](https://ziggit.dev/t/error-expected-type-t-found-t-with-types-imported-from-c-headers/12200/4 "2025-09-25T17:20:35Z")

</div>

> [@Sze](#):
>
> If you still use `@cImport` make sure that you only use it in one place, there you can declare it as a public declaration, then from the other place where you need it you can import and use that public declaration.

I actually do this with other libraries (for different reason), and it crossed my mind to try this.

Thank both of you for informative answers 🙂
