Я переношу серверный код, написанный на C, на Go, и он использует библиотеку шифрования, которую я действительно не хочу переписывать. Вместо этого я пытаюсь использовать Cgo для написания оболочки, чтобы остальная часть моего кода могла легко ее вызывать. Вот часть заголовка библиотеки:
// 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);
И вот фрагмент доказательства концепции, который я пытаюсь заставить работать:
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)
}
Я определил тестовую функцию (int test() { return 1; }
) в заголовке, и у меня нет проблем с ее вызовом из моего кода (через C.test()
) и ссылкой на какую-либо из констант #defined (C.CRYPT_BBCFG
), но при попытке запустить возникает следующая ошибка. установить 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
На данный момент я предполагаю, что просто не вызываю функцию с правильными аргументами. У меня сложилось впечатление, что cdata имеет тип *C.struct_CRYPT_SETUP
, ключ должен быть *byte
(хотя без & тоже не работает) и C.CRYPT_BLUEBURST типа... что-то. Попытка C.uchar(CRYPT_BLURBURST)
тоже ничего не меняет.
Любые предложения по компиляции этого кода?
Редактировать: забыл свою платформу, я использую Mac OS X 10.10
Edit2 (РЕШЕНО): точка Jsor об использовании unsafe.Pointer с адресом первого элемента ключа помогла, но мне также пришлось переместить исходные файлы C в тот же каталог, что и мой файл Go. Возникла еще одна ошибка типа в результате использования C.struct_CRYPT_DATA вместо C.CRYPT_DATA, поэтому, если кто-то еще столкнется с такими ошибками:
./goserv.go:18: cannot use cdata (type *C.struct_CRYPT_SETUP) as type *C.struct___0 in argument to _Cfunc_CRYPT_CreateKeys
Затем удалите префикс struct_ (хотя в документах cgo говорится, что именно так можно напрямую ссылаться на типы структур C)