Cgo 未定义引用
Cgo undefined reference
为什么在我的.go 文件中使用Cgo 时无法识别c 函数?
我遵循了所有过程并在godoc上尝试了示例,它可以但是这个不起作用,是什么原因?
文件夹结构
libsha.a
sha.cpp
sha.o
sha.h
main.go
代码
sha.h
#ifndef _SHA_H_
#define _SHA_H_
#include <stdlib.h>
#include "TYPE.h"
typedef struct {
U32 bits[2];
U32 input[16];
U32 state[5];
} SHA_CTX;
void SHA_Init(SHA_CTX *ctx);
void SHA_Update(SHA_CTX *ctx, U8 *in, int inbytes);
void SHA_Final(SHA_CTX *ctx, U8 *out);
void KS_SHA(U8 *out, U8 *in, int inbytes);
#endif
sha.cpp
#include "sha.h"
void SHA_Init(SHA_CTX *ctx)
{
ctx->state[0] = INIT_H0;
ctx->state[1] = INIT_H1;
ctx->state[2] = INIT_H2;
ctx->state[3] = INIT_H3;
ctx->state[4] = INIT_H4;
ctx->bits[0] = ctx->bits[1] = 0;
}
main.go
package main
// #cgo LDFLAGS: -L . -lsha
// #include "sha.h"
import "C"
import "unsafe"
type CPoint struct {
Point C.struct_SHA_CTX
}
func main() {
point := CPoint{Point: C.struct_SHA_CTX{}}
C.SHA_Init(point)
defer C.free(unsafe.Pointer(point))
}
错误
C:/TDM-GCC-64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: $WORK\b001\_x002.o: in function `_cgo_6280fd3fea2a_Cfunc_SHA_Init':
/tmp/go-build/cgo-gcc-prolog:49: undefined reference to `SHA_Init'
collect2.exe: error: ld returned 1 exit status
为什么SHA_Init函数无法识别?
您的 sha.cpp
文件不是 C
文件,而是 C++
文件。默认情况下,这意味着在编译时,它不会有 C 链接,这意味着 CGo 将无法调用它。
查看 以了解有关默认情况下为什么不起作用的更多信息。
解决方案
- 如果
sha.cpp
可以轻松转换为纯 C
文件,那将是最简单的。对于上面的代码,只需将其重命名为 sha.c
似乎对我有用。
- 如果这不可行,请查看 post:How to use C++ in Go
注意事项:
我必须进行一些重构才能使其正常工作,因为我缺少您的代码示例中使用的大量定义。
- 我无法使用
libsha.a
尝试此操作,并且不得不重新定义所有 U*
类型,因为我没有该文件(例如 U8
-> uint8_t
).
- 我不得不删除
SHA_Init
之外的函数,因为没有给出它们的实现。
- 为了编译,我将
sha.cpp
中的所有 INIT_H*
整数重命名为常量。
- 我在 Mac 上测试了这个,并使用了
clang
,但是 运行 你的代码给了我一个类似的错误,所以我相信解决方案会是类似的。
为什么在我的.go 文件中使用Cgo 时无法识别c 函数? 我遵循了所有过程并在godoc上尝试了示例,它可以但是这个不起作用,是什么原因?
文件夹结构
libsha.a
sha.cpp
sha.o
sha.h
main.go
代码
sha.h
#ifndef _SHA_H_
#define _SHA_H_
#include <stdlib.h>
#include "TYPE.h"
typedef struct {
U32 bits[2];
U32 input[16];
U32 state[5];
} SHA_CTX;
void SHA_Init(SHA_CTX *ctx);
void SHA_Update(SHA_CTX *ctx, U8 *in, int inbytes);
void SHA_Final(SHA_CTX *ctx, U8 *out);
void KS_SHA(U8 *out, U8 *in, int inbytes);
#endif
sha.cpp
#include "sha.h"
void SHA_Init(SHA_CTX *ctx)
{
ctx->state[0] = INIT_H0;
ctx->state[1] = INIT_H1;
ctx->state[2] = INIT_H2;
ctx->state[3] = INIT_H3;
ctx->state[4] = INIT_H4;
ctx->bits[0] = ctx->bits[1] = 0;
}
main.go
package main
// #cgo LDFLAGS: -L . -lsha
// #include "sha.h"
import "C"
import "unsafe"
type CPoint struct {
Point C.struct_SHA_CTX
}
func main() {
point := CPoint{Point: C.struct_SHA_CTX{}}
C.SHA_Init(point)
defer C.free(unsafe.Pointer(point))
}
错误
C:/TDM-GCC-64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: $WORK\b001\_x002.o: in function `_cgo_6280fd3fea2a_Cfunc_SHA_Init':
/tmp/go-build/cgo-gcc-prolog:49: undefined reference to `SHA_Init'
collect2.exe: error: ld returned 1 exit status
为什么SHA_Init函数无法识别?
您的 sha.cpp
文件不是 C
文件,而是 C++
文件。默认情况下,这意味着在编译时,它不会有 C 链接,这意味着 CGo 将无法调用它。
查看 以了解有关默认情况下为什么不起作用的更多信息。
解决方案
- 如果
sha.cpp
可以轻松转换为纯C
文件,那将是最简单的。对于上面的代码,只需将其重命名为sha.c
似乎对我有用。 - 如果这不可行,请查看 post:How to use C++ in Go
注意事项:
我必须进行一些重构才能使其正常工作,因为我缺少您的代码示例中使用的大量定义。
- 我无法使用
libsha.a
尝试此操作,并且不得不重新定义所有U*
类型,因为我没有该文件(例如U8
->uint8_t
). - 我不得不删除
SHA_Init
之外的函数,因为没有给出它们的实现。 - 为了编译,我将
sha.cpp
中的所有INIT_H*
整数重命名为常量。 - 我在 Mac 上测试了这个,并使用了
clang
,但是 运行 你的代码给了我一个类似的错误,所以我相信解决方案会是类似的。