Как связать статическую библиотеку Go с программой на C

Вопрос или проблема

Я пытаюсь вызвать функцию Go из программы на C. Я создал статическую библиотеку из моего исходного кода Go, но ld не может найти функцию, которую я хочу вызвать из программы на C.

Код Go:

package main

import "fmt"
import "C"

// (это можно назвать как угодно)
// export goCallbackHandler
func goCallbackHandler() C.int {
    i := Hello()
    return C.int(i)
}

func Hello() int {
    fmt.Println("Привет, мир!")
    return 0
}

func main() {
}

Код C:
(main.c)

#include "binding.h"

int main() {
     // Вызовите функцию из привязки
     return goCallbackHandler();
}

(binding.h)

extern int goCallbackHandler();

Я могу успешно собрать библиотеку с помощью go build -o libhello.a -buildmode=c-archive hello.go. Однако, когда я пытаюсь собрать часть на C с помощью gcc -o hello main.c -L. -lhello, я получаю ошибку

main.c:(.text+0xe): неопределенная ссылка на `goCallbackHandler'
collect2: error: ld вернул статус выхода 1

от ld

Ответ или решение

Для того чтобы связать статическую библиотеку Go с программой на C, необходимо учесть несколько важных моментов, чтобы избежать ошибок, таких как «undefined reference to ‘goCallbackHandler’». Давайте рассмотрим, как исправить вашу ситуацию шаг за шагом.

Шаг 1: Корректировка кода Go

Ваш код на Go имеет правильные компоненты, однако есть некоторые нюансы, на которые следует обратить внимание:

  1. Убедитесь, что функция, которую вы экспортируете, действительно экспортируется для использования в C. В Go функция должна быть экспортирована, если её имя начинается с заглавной буквы.

Пример кода Go

package main

import "C"
import "fmt"

// export GoCallbackHandler
func GoCallbackHandler() C.int {
    i := Hello()
    return C.int(i)
}

func Hello() int {
    fmt.Println("Hello, world!")
    return 0
}

func main() {}

Шаг 2: Генерация статической библиотеки

Для создания статической библиотеки выполните следующую команду в терминале:

go build -o libhello.a -buildmode=c-archive your_package_name.go

Обратите внимание, что your_package_name.go должен быть заменен на фактическое имя вашего файла.

Шаг 3: Создание заголовочного файла

Ваш заголовочный файл, binding.h, должен выглядеть следующим образом:

#ifndef BINDING_H
#define BINDING_H

extern int GoCallbackHandler();

#endif // BINDING_H

Шаг 4: Компиляция C-кода

Теперь, когда у вас есть и библиотека, и заголовочный файл, убедитесь, что вы правильно компилируете вашу C-программу. Вы должны указать компилятору GCC как библиотеку, так и сам файл библиотеки. Вот команда, которую вам нужно использовать:

gcc -o hello main.c -L. -lhello -pthread

Шаг 5: Проверка и запуск

Теперь, когда все компилируется без ошибок, запустите свою программу с помощью:

./hello

Если все прошло успешно, вы должны увидеть сообщение Hello, world!, что указывает на то, что функция GoCallbackHandler была успешно вызвана.

Примечания

  1. Убедитесь, что ваша библиотека (libhello.a) и ваш C-файл (main.c) находятся в одной директории, или используйте абсолютные пути.
  2. Вызывая функции Go из C, рекомендуется использовать -pthread, чтобы избежать проблем с зависимостями потока в Go.
  3. Обратите внимание на правила именования: убедитесь, что в ваших именах нет опечаток, и они соответствуют.

Следуя данным инструкциям, вы сможете успешно связать вашу библиотеку Go с программой на C.

Оцените материал
Добавить комментарий

Капча загружается...