首页 > 解决方案 > Cannot find symbol in linked library

问题描述

I'm trying to create go app, which uses some C++ code from sdk in shared library.
Added reference to target library with #cgo LDFLAGS:

#cgo LDFLAGS: -L/opt/cprocsp/lib/amd64 -lxades -v

and build go app with

go build -o main .

Compilation goes ok, but linking fails with error

/usr/bin/ld: $WORK/b001/_x003.o: undefined reference to symbol 'CryptReleaseContext'
/usr/bin/ld: //opt/cprocsp/lib/amd64/libcapi10.so.4: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status

Function CryptReleaseContext exists in /opt/cprocsp/lib/amd64/libxades.so.

With -v option I noticed linker arguments order

/usr/lib/gcc/x86_64-linux-gnu/8/collect2 ... $WORK/b001/_cgo_main.o $WORK/b001/_x001.o $WORK/b001/_x002.o $WORK/b001/_x003.o -lxades -lstdc++ ...

With Google I found that arguments order may be important, but I can't find a way to control them and stucking with it. How can I build app?

Example:
main.go

package main

import "log"

func main() {
    data := "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
        "<Envelope xmlns=\"urn:envelope\">" +
        "<Data>Hello, World!</Data>" +
        "<Node xml:id=\"nodeID\">Hello, Node!</Node>" +
        "</Envelope>"
    signed := Sign(data)
    log.Print(signed)
}

signer.go

package main

/*
#cgo LDFLAGS: -L/opt/cprocsp/lib/amd64 -lxades -v
#include <stdarg.h>
#include <stdlib.h>
#include "signer.h"
*/
import "C"
import "log"
import "unsafe"

func Sign(data string) (result string) {
    log.Print("Signing message")
    c_data := C.CString(data)
    defer C.free(unsafe.Pointer(c_data))
    c_result := C.CString(result)
    defer C.free(unsafe.Pointer(c_result))
    C.sign(c_data, c_result)
    return C.GoString(c_result)
}

signer.h

void sign(char* src, char *dst);

signer.cpp
SDK's example code, that uses functions from /opt/cprocsp/lib/amd64/libxades.so

...

extern "C" {
    void sign(char* src, char *dst){
        BYTE *pbToBeSigned = (BYTE *) src;
        DWORD cbToBeSigned = strlen(src);
        static XADES_SIGN_MESSAGE_PARA signParams = { sizeof(signParams) };
        initSignParams(&signParams);
        PCRYPT_DATA_BLOB pSignedMessage = 0;
        // Создаем подписанное сообщение
        if (!XadesSign(&signParams, NULL, FALSE, pbToBeSigned, cbToBeSigned, &pSignedMessage)) {
            cout << "XadesSign() failed" << endl;
            return;
        }

        vector<unsigned char> message(pSignedMessage->cbData);
        copy(pSignedMessage->pbData, pSignedMessage->pbData + pSignedMessage->cbData, message.begin());
        char* result = reinterpret_cast<char*>(message.data());
        strcpy(dst, result);
    }
}

Update

#cgo LDFLAGS: -L/opt/cprocsp/lib/amd64 -Wl,-rpath,/opt/cprocsp/lib/amd64 -lxades -v

didn't help

标签: c++goldcgo

解决方案


答案是第二个错误:

#cgo LDFLAGS: -L/opt/cprocsp/lib/amd64 -lxades -lcapi10 -lcapi20 -v

我第一次尝试添加时lcapi10- 错过了新错误lcapi20,而不是 10


推荐阅读