CGO неопределенная ссылка на `TIFFGetField’

#c #windows #go #cgo #lib

#c #Windows #Вперед #cgo #библиотека

Вопрос:

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

Проблема в том, что когда я теоретически настроил часть Go и хотел использовать свой код на C, он отбрасывает undefined reference to xxxx» с вызовами функций TIFFGetField, _TIFFmalloc, TIFFReadRGBAImage.

Вероятно, я даже неправильно импортирую библиотеку libtiff. Забавно, что первый код самого кода C TIFF* tif = TIFFOpen("foo.tif", "w"); не содержит ошибки ссылки на TIFFOpen, только другие (TIFFGetField, _TIFFmalloc, TIFFReadRGBAImage, _TIFFfree, TIFFClose)

мой код go

 package main

// #cgo CFLAGS: -Ilibs/libtiff/libtiff
// #include "tiffeditor.h"
import "C"

func main() {
    C.tiffEdit()
}
  
 #include "tiffeditor.h"
#include "tiffio.h"

void tiffEdit(){
    TIFF* tif = TIFFOpen("foo.tif", "w");
    if (tif) {
        uint32 w, h;
        size_t npixels;
        uint32* raster;

        TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, amp;w);
        TIFFGetField(tif, TIFFTAG_IMAGELENGTH, amp;h);
        npixels = w * h;
        raster = (uint32*) _TIFFmalloc(npixels * sizeof (uint32));
        if (raster != NULL) {
            if (TIFFReadRGBAImage(tif, w, h, raster, 0)) {
            //
            }
            _TIFFfree(raster);
        }
        TIFFClose(tif);
    }
}
  

Моя цель сначала — просто установить libtiff с моим кодом go и заставить его распознавать функции libtiff, чтобы я мог сосредоточиться на решении самой проблемы.

Комментарии:

1. Я удалил весь остальной код, чтобы убедиться, что в TIFFOpen нет ошибки ссылки, но она есть..

Ответ №1:

Если вы видите сообщение «неопределенная ссылка на xxx» в cgo. Очень вероятно, что вам не хватает ссылки на разделяемую библиотеку.

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

 // #cgo LDFLAGS: -lyour-lib
  

В приведенном выше случае я связываю свою программу go с динамической библиотекой C под названием «libyour-lib.so «.

Пример

Предполагается, что ваш источник TIFF происходит изhttp://www.simplesystems.org/libtiff /

Шаги

  1. Загрузите исходные коды
  2. Проверить README.md (или УСТАНОВИТЕ), чтобы прочитать руководство о том, как скомпилировать эту библиотеку C
  3. Следуйте предоставленным инструкциям и установите библиотеку C
  4. Если вы все делаете правильно, не изменяя настройки по умолчанию, вы должны найти заголовки tiff в /usr/local /include, а его динамические библиотеки — в /usr /local /lib
  5. Интегрирует эти материалы в вашу программу go, предоставляя правильные подсказки для компилятора cgo.

Коды

Я успешно собрал эту программу и выполнил, как ожидалось. Это может быть хорошей отправной точкой для вас.

 package main

// #cgo LDFLAGS: -ltiff
// #include "tiffio.h"
// #include <stdlib.h>
import "C"

import (
    "fmt"
    "unsafe"
)

func main() {
    path, perm := "foo.tif", "w"

    // Convert Go string to C char array. It will do malloc in C,
    // You must free these string if it no longer in use.
    cpath := C.CString(path)
    cperm := C.CString(perm)

    // Defer free the memory allocated by C.
    defer func() {
        C.free(unsafe.Pointer(cpath))
        C.free(unsafe.Pointer(cperm))
    }()

    tif := C.TIFFOpen(cpath, cperm)
    if tif == nil {
        panic(fmt.Errorf("cannot open %s", path))
    }

    C.TIFFClose(tif)
}
  

Комментарии:

1. прежде всего, спасибо, что пытались помочь моему тупице ^^ Кажется, в нем нет файлов .so или .a, только файлы кода и заголовков, может ли это быть проблемой?

2. программа не сообщает, что не находит файл (как говорит libtiff, чтобы включить tiffio.h), она просто показывает неопределенную ссылку на functionName

3. @Stephen Да, то, что вы сказали, абсолютно верно. Он нашел файл заголовка (tiffio.h), который предоставляет только определение для функций C, которые вы собираетесь использовать. Проблема в том, что компилятор не может найти его реализацию, которая покрывается некоторой библиотекой C, сгенерированной из tiffio.

4. Сначала вы должны скомпилировать tiffio, а затем связать свою программу с необходимыми библиотеками tiffio. Если вы работаете в UNIX-подобной системе, используйте «ls / usr /local / lib», чтобы проверить, есть ли какие-либо файлы с префиксом «libtiff». Эти объекты являются разделяемыми библиотеками, с которыми вы должны связать свою программу go.

5. @Stephen возможно, вы захотите проверить отредактированный ответ. Надеюсь, это может помочь.