使用Go语言与Swig封装的C++库

huangapple go评论85阅读模式
英文:

Using a swig wrapped c++ library with go

问题

我已经成功使用SWIG将一个大型的C++库进行了封装。我发布了这个模块,并且可以正常安装,但是在构建时出现了很多未定义引用的错误,这些错误指向生成的C文件中的函数。

我将生成的so库文件放在系统的lib目录中,并将库的头文件放在系统的include目录中,但是这并没有解决问题。我猜想我还需要一个用于封装的C文件的头文件,这样解释器才能知道so文件中的内容,但是由于SWIG没有生成这样的头文件,我不知道是否还有其他遗漏的东西。我打算尝试编写自己的头文件,看看是否可以解决这些错误,但即使可以解决,SWIG难道不应该自动完成这个工作吗?

我的源文件如下:

/** file: golibraw.i **/
%module librawgo
%{
#define LIBRAW_LIBRARY_BUILD
/* Put headers and other declarations here */
#include "libraw/libraw.h"
#include "libraw/libraw_alloc.h"
#include "libraw/libraw_const.h"
#include "libraw/libraw_datastream.h"
#include "libraw/libraw_internal.h"
#include "libraw/libraw_types.h"
#include "libraw/libraw_version.h"
%}

%include "libraw/libraw.h"
%include "libraw/libraw_alloc.h"
%include "libraw/libraw_const.h"
%include "libraw/libraw_datastream.h"
%include "libraw/libraw_internal.h"
%include "libraw/libraw_types.h"
%include "libraw/libraw_version.h"
cmake_minimum_required(VERSION 3.14)

if ( ${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR} )
    message( FATAL_ERROR "In-source builds not allowed. Please make a new directory and run CMake from there. You may need to remove CMakeCache.txt." )
endif()

find_package(SWIG 4.0 COMPONENTS python OPTIONAL_COMPONENTS go)
if(SWIG_FOUND)
  message("SWIG found: ${SWIG_EXECUTABLE}")
  include (UseSWIG)
  if(NOT SWIG_go_FOUND)
    message(FATAL_ERROR "SWIG go bindings cannot be generated")
  endif()
else()
    message(FATAL_ERROR "SWIG NOT FOUND")
endif()

set(PROJECT_NAME librawgo)
project(${PROJECT_NAME})

SET (CMAKE_LIBRARY_OUTPUT_DIRECTORY
        ${CMAKE_SOURCE_DIR}/librawgo
        CACHE PATH
        "Single Directory for all"
    )

find_program( CLANG_TIDY NAMES clang-tidy)

set(${PROJECT_NAME}_sources ${CMAKE_SOURCE_DIR}/src/librawgo.i )

swig_add_library(${PROJECT_NAME} TYPE SHARED LANGUAGE go SOURCES ${${PROJECT_NAME}_sources})

if(CLANG_TIDY)
set_property(
    TARGET ${PROJECT_NAME}
    PROPERTY CXX_CLANG_TIDY "${CLANG_TIDY}")
endif()

    set_property(TARGET ${PROJECT_NAME} PROPERTY SWIG_COMPILE_OPTIONS -go -intgosize 64 -cpperraswarn)
    set_property(TARGET ${PROJECT_NAME} PROPERTY SWIG_USE_TARGET_INCLUDE_DIRECTORIES TRUE)
    set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 11)
    set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD_REQUIRED ON)
    target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_SOURCE_DIR})
英文:

I have managed to successfully wrap a large C++ library with SWIG. I published the module and can install it okay, but when I go to build it I get a ton of undefined reference errors to the functions contained within the generated c file.

I placed the generated so lib file in my system lib directory, and placed the header files from the library into my system include directory, but this has not solved the problem. I am guessing that I need a header file for wrapped c file as well so the interpreter can know what's in the so file, but given that SWIG didn't generate one, I don't know if I am missing anything else. I'm going to try to write my own header file to see if that resolves the errors, but even if it does, shouldn't that be something that SWIG would do automatically?

My source files are below

/** file: golibraw.i **/
%module librawgo
%{
#define LIBRAW_LIBRARY_BUILD
/* Put headers and other declarations here */
#include "libraw/libraw.h"
#include "libraw/libraw_alloc.h"
#include "libraw/libraw_const.h"
#include "libraw/libraw_datastream.h"
#include "libraw/libraw_internal.h"
#include "libraw/libraw_types.h"
#include "libraw/libraw_version.h"
%}
%include "libraw/libraw.h"
%include "libraw/libraw_alloc.h"
%include "libraw/libraw_const.h"
%include "libraw/libraw_datastream.h"
%include "libraw/libraw_internal.h"
%include "libraw/libraw_types.h"
%include "libraw/libraw_version.h"
cmake_minimum_required(VERSION 3.14)

if ( ${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR} )
    message( FATAL_ERROR "In-source builds not allowed. Please make a new directory and run CMake from there. You may need to remove CMakeCache.txt." )
endif()

find_package(SWIG 4.0 COMPONENTS python OPTIONAL_COMPONENTS go)
if(SWIG_FOUND)
  message("SWIG found: ${SWIG_EXECUTABLE}")
  include (UseSWIG)
  if(NOT SWIG_go_FOUND)
    message(FATAL_ERROR "SWIG go bindings cannot be generated")
  endif()
else()
    message(FATAL_ERROR "SWIG NOT FOUND")
endif()

set(PROJECT_NAME librawgo)
project(${PROJECT_NAME})

SET (CMAKE_LIBRARY_OUTPUT_DIRECTORY
        ${CMAKE_SOURCE_DIR}/librawgo
        CACHE PATH
        "Single Directory for all"
    )

find_program( CLANG_TIDY NAMES clang-tidy)



set(${PROJECT_NAME}_sources ${CMAKE_SOURCE_DIR}/src/librawgo.i )


swig_add_library(${PROJECT_NAME} TYPE SHARED LANGUAGE go SOURCES ${${PROJECT_NAME}_sources})


if(CLANG_TIDY)
set_property(
    TARGET ${PROJECT_NAME}
    PROPERTY CXX_CLANG_TIDY "${CLANG_TIDY}")
endif()

    set_property(TARGET ${PROJECT_NAME} PROPERTY SWIG_COMPILE_OPTIONS -go -intgosize 64 -cpperraswarn)
    set_property(TARGET ${PROJECT_NAME} PROPERTY SWIG_USE_TARGET_INCLUDE_DIRECTORIES TRUE)
    set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 11)
    set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD_REQUIRED ON)
    target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_SOURCE_DIR})

答案1

得分: 1

原因是Go编译器对于库librawgo.so一无所知。

将以下行放置在librawgo.go中的C注释的顶部:

#cgo LDFLAGS: -L<path/to/dir/with/librawgo.so> -lrawgo -lraw

这个指令告诉编译器将此行添加到链接器标志中。

抱歉,我不知道如何修改您的CMake和SWIG设置以自动生成这行代码。

英文:

The reason is that Go compiler has no idea about the library librawgo.so.

Put the following line to the top of the C comment in librawgo.go:

#cgo LDFLAGS: -L&lt;path/to/dir/with/librawgo.so&gt; -lrawgo -lraw

This instruction tells the compiler to add this line to the linker flags.

Sorry, I don't know how to modify your CMake and SWIG settings to generate this line automatically.

huangapple
  • 本文由 发表于 2022年10月7日 04:45:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/73979843.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定