Issues about calling functions in abc.so

$cat abc.c

#include <stdio.h>

 int add(int a, int b) {
      return a + b; 
 }

 void print_message(const char* message) {
       printf("Message: %s\n", message);         
 }  

$gcc -shared -fPIC -o abc.so abc.c
There will be no .hash section but .gnu_hash section in abc.so. It causes std.DynLib.open
complain “error.ElfHashTableNotFound”

with the help of deepseek,
$gcc -shared -fPIC -Wl,–hash-style=both -o abc.so abc.c

fixes it !

$ nm -D abc.so
U __cxa_atexit@LIBC
U __cxa_finalize@LIBC
U __register_atfork@LIBC
00000000000046d0 T add
00000000000046f0 T print_message
U printf@LIBC

$cat main.zig

const std = @import("std"); 

 pub fn main() !void { 
// Load the shared library 
    var lib = try std.DynLib.open("abc.so");  
 // Resolve the C functions                        
    const add = lib.lookup(*const fn (c_int, c_int) c_int, "add") orelse {           
       std.debug.print("Failed to find 'add' function\n", .{});                                  
    return;    
 };

 const print_message = lib.lookup(*const fn ([*:0]const u8) void, "print_message") orelse {          
         std.debug.print("Failed to find 'print_message' function\n", .{});  
        return;   
  };                
// Call the C functions                           
   const result = add(3, 4);
   std.debug.print("Result from C: {}\n",.{result});                                                                                          
   print_message("Hello from Zig!"); 
 }

Why cannot the lookup find functions in abc.so ?

Regards !

std.DynLib.open Accepts a path not a name try passing ./abc.so if it’s on the same directory.

1 Like

Also make sure the calling convention is that of C otherwise you’ll encounter problems.

*const fn (c_int, c_int) c_int*const fn (c_int, c_int) callconv(.C) c_int
*const fn ([*:0]const u8) void*const fn ([*:0]const u8) callconv(.C) void

1 Like

You need newer zig to load .so’s containing only .gnu_hash with ElfDynLib

see also: https://ziggit.dev/t/loading-libvulkan-so-1-on-linux-with-std-elfdynlib

1 Like

Thanks for all your suggestions ! Now ‘add’ works but ‘print_message’ segfault !

$ ./main
Result from C: 7 ← add(3,4)

print_message pointer: fn ([*:0]const u8) callconv(.C) void@7beff336f0 Segmentation fault at address 0x0 ???:?:?: 0x0 in ??? (???)

Regards !

How are you building main.zig? I can reproduce your error when I build not linking libc:

$ zig build-exe main.zig
$ ./main
Result from C: 7
Segmentation fault at address 0x0
???:?:?: 0x0 in ??? (???)

but everything works fine with libc linked:

$ zig build-exe main.zig -lc
$ ./main
Result from C: 7
Message: Hello from Zig!

The shared object abc.so is using the printf function from libc, thus it will segfault on that call if the executable is not dynamically linked against libc.

1 Like

$ ldd abc.so
libdl.so => /system/lib64/libdl.so libc.so => /system/lib64/libc.so
ld-android.so => /system/lib6*4/ld-android.so

$ zig build-exe main.zig -lc
warning: Encountered error: FileNotFound, falling back to default ABI and dynamic linker. error: unable to create compilation: LibCRuntimeNotFound

$ uname -a
Linux localhost 5.4.254-android12-9-g619997ff2210 #1 SMP P REEMPT Fri Feb 7 14:59:01 CST 2025 aarch64 Android

So it is not code problem but android platform.

Thanks very much !