Below is a working example in C. Once you have
that going, then add the CGO layer on top to call from Go.
Note I seem to recall you might have to mark your C function as //extern 
...maybe, if 
in a separate C file and not inline in the .go file... read the CGO docs
in full for details.

$ cat libexample.c
#include <stdio.h>

int multiply(int a, int b) {
    return a * b;
}

$ gcc -shared -o libexample.so -fPIC libexample.c

$ cat dynamic_loading.c
#include <stdio.h>
#include <dlfcn.h>
#include <stdlib.h>

int main() {
    // Open the shared library
    void* handle = dlopen("./libexample.so", RTLD_LAZY);
    if (!handle) {
        fprintf(stderr, "Error loading library: %s\n", dlerror());
        return 1;
    }

    // Get the function pointer by name
    int (*multiply)(int, int) = dlsym(handle, "multiply");
    if (!multiply) {
        fprintf(stderr, "Error finding function: %s\n", dlerror());
        dlclose(handle);
        return 1;
    }

    // Call the function
    int result = multiply(5, 7);
    printf("5 * 7 = %d\n", result);

    // Clean up
    dlclose(handle);
    return 0;
}

$ gcc -o user_of_library dynamic_loading.c

$ ./user_of_library
5 * 7 = 35

Go host, from AI but does run

package main /* #cgo LDFLAGS: -ldl #include <dlfcn.h> #include <stdlib.h> 
#include <stdio.h> // Define the function type that matches our C function 
typedef int (*multiply_func)(int, int); // Helper function to load and call 
the multiply function int call_multiply(int a, int b) { void* handle = 
dlopen("./libexample.so", RTLD_LAZY); if (!handle) { fprintf(stderr, "Error 
loading library: %s\n", dlerror()); return -1; } // not C, but you'll need 
the moral equivalent of // defer dlclose(handle); // to clean up. 
multiply_func multiply = (multiply_func)dlsym(handle, "multiply"); if 
(!multiply) { fprintf(stderr, "Error finding function: %s\n", dlerror()); 
return -1; } return multiply(a, b); } */ import "C" import "fmt" func 
main() { // Call the C function through our wrapper result := 
C.call_multiply(C.int(5), C.int(7)) if result == -1 { fmt.Println("Error 
calling multiply function") return } fmt.Printf("5 * 7 = %d\n", 
int(result)) }

$ go run user_of_lib_from_go.go
5 * 7 = 35

On Thursday, May 15, 2025 at 10:45:00 AM UTC+1 Bruno Albuquerque wrote:

> You can not directly call a C function pointer from Go. You will need a 
> CGO wrapper that calls it and them you call that wrapper from Go.
>
> -Bruno
>
>
> On Thu, May 15, 2025, 5:20 AM rudeus greyrat <rudeusqu...@gmail.com> 
> wrote:
>
>> Hello,
>>
>> Thanks for your answer.
>>
>> Three points to note:
>>
>>    - I never asked how to create an so, I already have a given so :/
>>    - No need to provide the code because the issue is simple to 
>>    describe: I have an address of a function in a Go variable, how to call 
>> it ?
>>    - AI is garbage (even though I use it)
>>
>> I thought about using assembly with a call instruction but I hoped 
>> someone knowledgable would tell me there is a built in Go function for that.
>>
>> Regards,
>> Rudeus
>>
>>
>>
>> Le jeudi 15 mai 2025 à 02:46:18 UTC+2, Kurtis Rader a écrit :
>>
>>> On Wed, May 14, 2025 at 4:17 PM rudeus greyrat <rudeusqu...@gmail.com> 
>>> wrote:
>>>
>>>> I am still a beginner in Linux internals so please bear with me.
>>>>
>>>> I have a ".so" that export "helloworld" function.
>>>>
>>>> I load the ".so" using CGO by:
>>>>
>>>>    1. Creating a file descriptor
>>>>    2. using ```write``` to write the so to it
>>>>
>>>> A shared library (".so" file) has a complex structure. You normally 
>>> create one using a compiler and related tools. For example, the Go compiler 
>>> can create a .so file from Go source code using a command like
>>>
>>> go build -buildmode=c-shared -o mylib.so
>>>
>>> It seems unlikely you are creating a valid .so file by opening an empty 
>>> file and writing to it unless you are simply copying one .so file to 
>>> another file. 
>>>
>>>>
>>>>    1. Get a handle using ```dlopen```
>>>>    2. Get the address of ```helloworld``` symbol using ```dlsym```
>>>>
>>>> The address of "helloworld" is saved in a go variable called 
>>>> ```address```
>>>>
>>>> How to call ```address``` ?
>>>>
>>>> On windows I am able to call address using ```syscall.SyscallN```. On 
>>>> Linux I tried with 
>>>> ```
>>>> r1, r2, err := syscall.Syscall(address, 0, 0, 0)
>>>> ```
>>>>
>>>> And I get "function not implemented" error.
>>>>
>>>
>>> I can't speak to Windows but on Unix like operating systems, such as 
>>> Linux, a function in a shared library is a user space function, not a 
>>> kernel entry point. A syscall is the way you call OS kernel functions, not 
>>> user space functions. I wouldn't expect syscall.Syscall() to work on 
>>> Windows when passed the address of a function in a DLL. Did you actually 
>>> confirm that it does work when passed the address of a DLL user space 
>>> function? In any case this definitely won't work on Linux.
>>>
>>> I searched for "how to call a function in a shared library in go" in 
>>> Chrome and the results included an AI generated example of how to do this 
>>> along with links to many articles and other sources such as StackOverflow. 
>>> If you're still having problems ask again but show us the source code you 
>>> wrote and the commands you ran to compile it.
>>>
>>> -- 
>>> Kurtis Rader
>>> Caretaker of the exceptional canines Junior and Hank
>>>
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to golang-nuts...@googlegroups.com.
>> To view this discussion visit 
>> https://groups.google.com/d/msgid/golang-nuts/6df9116e-d5dd-4b93-bd0d-45df42c24626n%40googlegroups.com
>>  
>> <https://groups.google.com/d/msgid/golang-nuts/6df9116e-d5dd-4b93-bd0d-45df42c24626n%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion visit 
https://groups.google.com/d/msgid/golang-nuts/e29eac0a-6735-4e13-a90c-cc4e14572587n%40googlegroups.com.

Reply via email to