我有一个使用JNA调用Go Func的Java程序。这是Java中Go函数的接口:
public interface GPG extends Library {
// GoString class maps to: C type struct { const char *p; GoInt n; }
public class GoString extends Structure {
public static class ByValue extends GoString implements Structure.ByValue {}
public String p;
public long n;
protected List getFieldOrder(){
return Arrays.asList(new String[]{"p","n"});
}
}
// Foreign functions
public GoString.ByValue decrypt(GoString.ByValue encString, GoString.ByValue secretKeyring, GoString.ByValue passphrase);
}
Go中的func签名是:
func decrypt(encString string, secretKeyring string, passphrase string) string
Go生成的C标头有:
/* Created by "go tool cgo" - DO NOT EDIT. */
/* package command-line-arguments */
#line 1 "cgo-builtin-prolog"
#include <stddef.h> /* for ptrdiff_t below */
#ifndef GO_CGO_EXPORT_PROLOGUE_H
#define GO_CGO_EXPORT_PROLOGUE_H
typedef struct { const char *p; ptrdiff_t n; } _GoString_;
#endif
/* Start of preamble from import "C" comments. */
/* End of preamble from import "C" comments. */
/* Start of boilerplate cgo prologue. */
#line 1 "cgo-gcc-export-header-prolog"
#ifndef GO_CGO_PROLOGUE_H
#define GO_CGO_PROLOGUE_H
typedef signed char GoInt8;
typedef unsigned char GoUint8;
typedef short GoInt16;
typedef unsigned short GoUint16;
typedef int GoInt32;
typedef unsigned int GoUint32;
typedef long long GoInt64;
typedef unsigned long long GoUint64;
typedef GoInt64 GoInt;
typedef GoUint64 GoUint;
typedef __SIZE_TYPE__ GoUintptr;
typedef float GoFloat32;
typedef double GoFloat64;
typedef float _Complex GoComplex64;
typedef double _Complex GoComplex128;
/*
static assertion to make sure the file is being used on architecture
at least with matching size of GoInt.
*/
typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1];
typedef _GoString_ GoString;
typedef void *GoMap;
typedef void *GoChan;
typedef struct { void *t; void *v; } GoInterface;
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
#endif
/* End of boilerplate cgo prologue. */
#ifdef __cplusplus
extern "C" {
#endif
extern GoString decrypt(GoString p0, GoString p1, GoString p2);
#ifdef __cplusplus
}
#endif
我使用以下代码从Java调用Go Func:
GPG gpg = (GPG) Native.loadLibrary("C:/lib/gpg.dll", GPG.class);
GPG.GoString.ByValue encString = new GPG.GoString.ByValue();
encString.p = value;
encString.n = encString.p.length();
GPG.GoString.ByValue secretKeyring = new GPG.GoString.ByValue();
secretKeyring.p = "c:/gnupg/secring.gpg";
secretKeyring.n = secretKeyring.p.length();
GPG.GoString.ByValue passphrase = new GPG.GoString.ByValue();
passphrase.p = "SecretPassPhrase";
passphrase.n = passphrase.p.length();
GPG.GoString.ByValue decValue = gpg.decrypt(encString, secretKeyring, passphrase);
显然正在调用func并处理结果字符串的返回。但它产生:“恐慌:运行时错误:cgo结果有Go指针” 如何从Go获取String结果? 使用go版本go1.10 windows / amd64,JNA 4.5.1,Java 1.8.0_152
答案 0 :(得分:1)
您的GO函数应如下所示:
//export decrypt
func decrypt(encString string, secretKeyring string, passphrase string) *C.char {
//... your code here
var str string = "returning string"
return C.CString(str)
}
Java接口:
public String decrypt(GoString.ByValue encString, GoString.ByValue secretKeyring, GoString.ByValue passphrase);
答案 1 :(得分:0)
const char *
中的_GoString_
应使用Pointer
,然后使用提供的偏移量Pointer.getString()
来获取实际字符串。
如果Go本身拒绝string
返回值,则您可能不得不填充调用者提供的缓冲区。