我正在编写一个本地库,它使用cgo提供了一个C api。我有一个C头文件,其中包括一个常量定义,但当我使用cgo将其包含在一个包中,然后在go中将该包导入main时,我会得到一个
multiple definition...
生成时出现链接器错误:
C:\Users\danie\AppData\Local\Temp\go-link-1146178960\000011.o:C:\Temp\cgo-error\mypackage/errors.h:29: multiple definition of `MYMODULE_ERROR_STRS'; C:\Users\danie\AppData\Local\Temp\go-link-1146178960\000010.o:C:/Temp/cgo-error/mypackage/errors.h:29: first defined here
collect2.exe: error: ld returned 1 exit status
下面的示例代码使用了此答案中给出的错误处理示例:
https://stackoverflow.com/a/59221452/1324919
main.go:
package main
import "C"
import "example.com/cgo-error/mypackage"
func main() {}
//export exported_function
func exported_function() {
mypackage.CallCFunction()
}
mypackage.go(包括C头文件):
package mypackage
// #include "errors.h"
import "C"
func CallCFunction() {
_ = C.mymodule_func1()
}
错误。h:
#ifndef ERRORS_H_
#define ERRORS_H_
/// @brief Error codes for library "mymodule"
typedef enum mymodule_error_e
{
/// No error
MYMODULE_ERROR_OK = 0,
MYMODULE_ERROR_INVARG,
MYMODULE_ERROR_NOMEM,
MYMODULE_ERROR_MYERROR,
MYMODULE_ERROR_COUNT,
} mymodule_error_t;
// Array of strings to map enum error types to printable strings
const char *const MYMODULE_ERROR_STRS[] =
{
"MYMODULE_ERROR_OK",
"MYMODULE_ERROR_INVARG",
"MYMODULE_ERROR_NOMEM",
"MYMODULE_ERROR_MYERROR",
};
// To get a printable error string
const char *mymodule_error_str(mymodule_error_t err);
// Other functions in mymodule
mymodule_error_t mymodule_func1(void);
mymodule_error_t mymodule_func2(void);
mymodule_error_t mymodule_func3(void);
#endif
错误。c:
#include "errors.h"
#include <stdio.h>
/// @brief Function to get a printable string from an enum error type
/// @param[in] err a valid error code for this module
/// @return A printable C string corresponding to the error code input above, or NULL if an invalid error code
/// was passed in
const char *mymodule_error_str(mymodule_error_t err)
{
const char *err_str = NULL;
// Ensure error codes are within the valid array index range
if (err >= MYMODULE_ERROR_COUNT)
{
goto done;
}
err_str = MYMODULE_ERROR_STRS[err];
done:
return err_str;
}
// Let's just make some empty dummy functions to return some errors; fill these in as appropriate for your
// library module
mymodule_error_t mymodule_func1(void)
{
return MYMODULE_ERROR_OK;
}
mymodule_error_t mymodule_func2(void)
{
return MYMODULE_ERROR_INVARG;
}
mymodule_error_t mymodule_func3(void)
{
return MYMODULE_ERROR_MYERROR;
}
在我看来,将头文件包含在
mypackage.go
并将其包含在
errors.c
导致go链接器导入它两次,当
mypackage
在中导入
main
.
有什么办法绕过这个吗?