Golang中如何导入静态库

Golang中如何导入静态库 大家好, 我通过Visual Code在Windows上创建了一个C++静态库。 我构建了这个库,并且没有发现任何错误。 但是当在Windows上使用cgo与Golang导入时,出现了错误。 我检查后发现它们都使用的是64位架构。 请帮助我如何将Visual Code构建的C++静态库导入到使用CGO的Golang中。

这是收到的错误信息:

PS C:\Users\Administrator\Desktop\static_lib\window> go run .\main.go
# command-line-arguments
C:\Program Files\Go\pkg\tool\windows_amd64\link.exe: running gcc failed: exit status 1
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\ADMINI~1\AppData\Local\Temp\2\go-link-1866661389\000001.o: in function `_cgo_4edeb0dd26e3_Cfunc_hello_world':
/tmp/go-build/main.cgo2.c:49: undefined reference to `__imp_hello_world'
collect2.exe: error: ld returned 1 exit status

更多关于Golang中如何导入静态库的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

这是我的 C++ 代码:

#ifndef PCH_H
#define PCH_H

#ifdef MY_WINDOW_EXPORTS
#define MY_API __declspec(dllexport)
#else
#define MY_API __declspec(dllimport)
#endif

// add headers that you want to pre-compile here
#include "framework.h"


#ifdef __cplusplus
extern "C" {
#endif
	// Your prototype or Definition 
	MY_API const char* hello_world();
#ifdef __cplusplus
}
#endif


#endif //PCH_H
// pch.cpp: source file corresponding to the pre-compiled header

#include "pch.h"

// When you are using pre-compiled headers, this source file is necessary for compilation to succeed.


const char* hello_world()
{
    const char *message = "hello world";
    return message;
}

更多关于Golang中如何导入静态库的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


这是一个典型的CGO链接静态库时的符号引用问题。错误信息显示链接器找不到 hello_world 函数的实现,这通常是因为静态库没有正确链接或符号命名不匹配。

首先,确保你的项目结构如下:

project/
├── main.go
├── mylib.a
└── mylib.h

main.go 示例:

package main

// #cgo CFLAGS: -I.
// #cgo LDFLAGS: -L. -lmylib
// #include "mylib.h"
import "C"

func main() {
    C.hello_world()
}

mylib.h 示例:

#ifndef MYLIB_H
#define MYLIB_H

#ifdef __cplusplus
extern "C" {
#endif

void hello_world();

#ifdef __cplusplus
}
#endif

#endif

关键步骤:

  1. 确保C++函数使用C链接: 在C++源文件中,必须使用 extern "C" 包装函数声明:

    // mylib.cpp
    #include <iostream>
    
    extern "C" {
        void hello_world() {
            std::cout << "Hello from C++ static library!" << std::endl;
        }
    }
    
  2. 正确构建静态库: 使用MinGW的g++构建64位静态库:

    g++ -c mylib.cpp -o mylib.o
    ar rcs libmylib.a mylib.o
    
  3. Go文件中的CGO指令

    // #cgo CFLAGS: -I.
    // #cgo LDFLAGS: -L. -lmylib
    // #include "mylib.h"
    import "C"
    
  4. 如果问题仍然存在,尝试显式指定库文件

    // #cgo LDFLAGS: ./libmylib.a
    
  5. 检查符号表: 使用以下命令验证静态库中是否存在正确的符号:

    nm libmylib.a | grep hello_world
    

    应该显示类似 T hello_world 的输出(不是 __imp_hello_world)。

  6. Windows特定的解决方案: 如果使用MinGW,可能需要添加 -static 标志:

    // #cgo LDFLAGS: -static -L. -lmylib
    
  7. 完整的工作示例

mylib.cpp:

#include <iostream>

extern "C" {
    void hello_world() {
        std::cout << "Hello from C++ static library!" << std::endl;
    }
    
    int add_numbers(int a, int b) {
        return a + b;
    }
}

main.go:

package main

/*
#cgo CFLAGS: -I.
#cgo LDFLAGS: -L. -lmylib
#include "mylib.h"
*/
import "C"
import "fmt"

func main() {
    C.hello_world()
    
    result := C.add_numbers(10, 20)
    fmt.Printf("Result from C++: %d\n", int(result))
}

构建命令:

# 构建静态库
g++ -c mylib.cpp -o mylib.o
ar rcs libmylib.a mylib.o

# 运行Go程序
go run main.go

如果仍然遇到 __imp_ 前缀问题,这可能是MinGW的导入库行为。可以尝试在CGO标志中添加 -Wl,--allow-multiple-definition

// #cgo LDFLAGS: -Wl,--allow-multiple-definition -L. -lmylib

或者使用 __declspec(dllexport) 的方式导出函数:

#ifdef __cplusplus
extern "C" {
#endif

__declspec(dllexport) void hello_world();

#ifdef __cplusplus
}
#endif
回到顶部