I’m sorry for the bold font here below but I couldn’t understand how to get rid of it.
I want zig to import a C file and let zig compile it for me. The C file also include a .h file that defines a struct. I have simplified my real files here but the problem is the same.
----------------------------------simple.h------------------------
I want to call add_value() from zig with a legal value of s_ptr->ptr_to_val .
I declare my struct variable in the test part in main.zig like this.
-------------------------------------------------main.zig-----------------------------
const test_file = @cImport(
{
@cInclude("simple.c");
});
test "simple test" {
var ret: c_ulong = undefined;
var st = test_file.simple{.dummy = 2, .ptr_to_val = undefined};
// How to give the st.ptr_to_val a value that I can use when calling add_test() ?
ret = test_file.add_value(st.ptr_to_val)
}
Oh and also, it is generally a bad idea to @cInclude non-header files.
The zig internal parser/translator for C files which gets invoked on @cImport has sometimes trouble translating more complex implementations.
Instead the recommended way is to add C source files to the build.zig using exe.addCSourceFile and only @cInclude the header files.
Using undefined means that you make a promise to the zig compiler that you are going to set the value somehow later.
Zig compiler can put nothing (leave it uninitialized) or might set it to alternating 0 and 1 bits (0xAA bytes) in debug mode.
See: undefined in Zig Language Reference
Hello again and thanks. I got it to work with your trick with &ret.
I then include the .h, in main.zig, and adding my C-file in build.zig like this.
As you can see I’m only interested to build and run the test.
Now I got link errors like (error: lld-link: undefined symbol: MainTimer_Init)
To me it looks that I miss to link my C file or perhaps it is not even compiled.
Can you see what I’m doing wrong?
The only thing I see is that you are missing unit_tests.linkLibC(); and also linkLibCpp(). You need to explicitly link the C and C++ standard libraries if you use them.
But that wouldn’t explain this particular linker error. Are there other errors before that in the output?
The MainTimer.cpp file doesn’t use anything external so it should not be necessary to link the standard libs. There is no errors before the one I describe here above.
Dimdin can you elaborate around how to prefix the definition with extern “C”. I don’t understand how to do it.
By the way, MainTimer.cpp is a real production file and it is a pure C file. I don’t know why it is named .cpp. I guess it has something to do with our build system.
Thanks gonzo, now I know it is compiled with C++ compiler.
As you can understand I’m new to zig, can you please show me, from my build.zig here above, how to prefix it with extern C.
When I try I only got errors.
Thanks gonzo, but then I have to change in the production files and that is not so god. I realize that is bad practice to name a C file .cpp but we have a lot of them unfortunately. Do you know of any trick that can be used in build.zig instead?
Keep in mind we are really talking about tricks here. As @leso suggested, you could export your symbol from a separate C++ file. You could also create blah.c as a symlink pointing to your C++ file, and compile that with a C compiler.