I'm porting some server code I wrote in C over to Go and it uses an encryption library I really don't want to rewrite. Instead I'm trying to use Cgo to write a wrapper so that the rest of my code can call it more easily. Here's part of the header for the lib:
// encryption/encryption.h
#define CRYPT_BBCFG 1
typedef struct {
// ...bunch of fields...
uint32_t bb_posn;
} CRYPT_SETUP;
int CRYPT_CreateKeys(CRYPT_SETUP* cs, void* key, unsigned char type);
And here's the proof-of-concept snippet I'm trying to get to work:
package goserv
//#include "encryption/encryption.h"
import "C"
func main() {
cdata := new(C.struct_CRYPT_SETUP)
key := make([]byte, 48)
C.CRYPT_CreateKeys(cdata, &key, C.CRYPT_BLUEBURST)
}
I defined a test function (int test() { return 1; }
) in the header and have no problem calling that from my code (via C.test()
) nor referencing any of the #defined'd constants (C.CRYPT_BBCFG
) but get the following error when I attempt to run go install goserv:
Undefined symbols for architecture x86_64:
"_CRYPT_CreateKeys", referenced from:
__cgo_e89359206bf1_Cfunc_CRYPT_CreateKeys in goserv.cgo2.o
(maybe you meant: __cgo_e89359206bf1_Cfunc_CRYPT_CreateKeys)
ld: symbol(s) not found for architecture x86_64
At this point I'm assuming I'm just not calling the function with the correct arguments. I was under the impression that cdata is of type *C.struct_CRYPT_SETUP
, key should be *byte
(though it doesn't work without the & either) and C.CRYPT_BLUEBURST of type...something. Trying C.uchar(CRYPT_BLURBURST)
also doesn't change anything.
Any suggestions on getting this code to compile?
Edit: Forgot my platform, I'm running Mac OS X 10.10
Edit2 (SOLVED): Jsor's point about using unsafe.Pointer with the address of the first element of key helped but I also had to move my C source files into the same directory as my Go file. There was another type error resulting from using C.struct_CRYPT_DATA instead of C.CRYPT_DATA, so if anyone else runs into errors like this:
./goserv.go:18: cannot use cdata (type *C.struct_CRYPT_SETUP) as type *C.struct___0 in argument to _Cfunc_CRYPT_CreateKeys
Then remove the struct_ prefix (though the cgo docs say that's how to directly reference C struct types)