c++ - 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
解决方案
答案是第二个错误:
#cgo LDFLAGS: -L/opt/cprocsp/lib/amd64 -lxades -lcapi10 -lcapi20 -v
我第一次尝试添加时lcapi10
- 错过了新错误lcapi20
,而不是 10
推荐阅读
- wpf - 扩展节点后数据绑定 TreeView 未更新
- linux - 不小心从redis中删除了一张表,有没有类似回滚的操作?
- ios - iOS 10 用户通知不允许间隔重复通知
- javascript - Html5 视频在 chrome 中的页面加载时不会自动播放?
- windows - 在 Windows 2016 上使用 stop-server -p ../pid.txt -f 命令时,Cassandra 服务器正在重新启动
- android - 将我的应用程序链接到 Google Play
- python - 除了(python,爬虫)的可能性
- java - Spring(自动装配)组件在同一个类中使用多个
- c# - Visual Studio 2017 仅具有适用于 .NET Core 2.x 的脱机 Nuget 包。如何获得在线包裹?
- php - 如何将数组数组映射到单个关联数组?