0

Why the c function is not recognized in my .go file when using Cgo? I followed all the process and tried the example on godoc, it worked but this one does not work, what is the reason?

folder structure

libsha.a

sha.cpp

sha.o

sha.h

main.go

Code

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))

}

Error

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

Why the SHA_Init function is not recognized?

Baziwe
  • 27
  • 1
  • 9

1 Answers1

1

Your sha.cpp file is not a C file, it's a C++ file. By default, this means that when compiled, it won't have C linkage, meaning CGo will have no way to call it.

Check out https://stackoverflow.com/a/1041880/2911436 for more information as to why it won't work by default.

Solutions

  1. If sha.cpp can be easily converted to a pure C file, that would be the easiest. In the case of your code above, simply renaming it to sha.c seemed to work for me.
  2. If that's not feasible, check out the post: How to use C++ in Go

Caveats:

I had to do a bit of refactoring in order to get this to work as I lacked a lot of the definitions used in your code samples.

  • I couldn't try this with a libsha.a, and had to redefine all U* types as I didn't have the file (e.g. U8 -> uint8_t).
  • I had to delete functions aside from SHA_Init as their implementations weren't given.
  • I renamed all of the INIT_H* ints in sha.cpp to be some constant in order to compile.
  • I tested this on a Mac, and used clang, however running your code gave me a similar error so I believe the solution will be similar.
John
  • 549
  • 4
  • 12
  • Thank you John, you are right I should try the link you shared for c++ and go, but I think it makes the compilation painful!!! I should try to convert it into C or reprogram the code in C calling the .h files – Baziwe Aug 07 '20 at 00:17