为了账号安全,请及时绑定邮箱和手机立即绑定

尝试编译 Go 共享对象以通过 JNI 从 Java 调用时出错

尝试编译 Go 共享对象以通过 JNI 从 Java 调用时出错

Go
慕码人2483693 2022-08-09 20:11:55
我正在尝试通过JNI调用从Java调用Go函数。Java编译是可以的。当我尝试构建Go共享对象(.so)时,它给我带来了关于可从Java调用的C函数包装器的“多个定义”的错误。这是Java代码:package yada.yada.locksmith;import java.io.*;public class Locksmith {   private native void setup(String ClientID, String ClientSecret, String RedirectURL, String AuthURL, String TokenURL, String UserInfURL);   private native String auth(String user, String pw);   static {      System.loadLibrary("Locksmith");   }   public static void Locksmith(String[] args) {      Locksmith locksmith = new Locksmith();      locksmith.setup(         "yadayadayadayadayadayadayadayadayadayada",         "yadayadayadayadayadayadayadayadayadayada",         "https://yada.yada/Yada/yada",         "https://yada.yada/Yada/yada2",         "https://yada.yada/Yada/yada3",         "https://yada.yada/Yada/yada4"      );      // Create the console object      Console cnsl = System.console();      if (cnsl == null) {         System.out.println("No console available");         return;      }      String user = cnsl.readLine("Enter username : ");      char[] pw = cnsl.readPassword("Enter password : ");      System.out.println(locksmith.auth(user,new String(pw)));   }}我用以下公式编译它:javac Locksmith.java然后我生成了头文件:javac -h .锁匠.java这是生成的文件:/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class yada_yada_locksmith_Locksmith */#ifndef _Included_yada_yada_locksmith_Locksmith#define _Included_yada_yada_locksmith_Locksmith#ifdef __cplusplusextern "C" {#endif/* * Class:     yada_yada_locksmith_Locksmith * Method:    setup * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V */JNIEXPORT void JNICALL Java_yada_yada_locksmith_Locksmith_setup  (JNIEnv *, jobject, jstring, jstring, jstring, jstring, jstring, jstring);
查看完整描述

1 回答

?
心有法竹

TA贡献1866条经验 获得超5个赞

cgo 文档中的以下问题是:


在文件中使用 //export 会对前导码施加限制:由于它被复制到两个不同的 C 输出文件中,因此它不能包含任何定义,只能包含声明。如果文件同时包含定义和声明,则两个输出文件将生成重复的符号,并且链接器将失败。为避免这种情况,必须将定义放在其他文件的序言中,或放在 C 源文件中。


移动线条


extern void Setup(char *, char *, char *, char *, char *, char *);

extern char *Auth(char *, char *);

到 该文件和 C 定义将生成以下成功构建的前导码:locksmith.hlocksmith.c


/*

#cgo CFLAGS: -I/usr/local/bin/jdk-15.0.1/include -I/usr/local/bin/jdk-15.0.1/include/linux


#include "locksmith.h"

*/

import "C"

的开头将包含以下内容:locksmith.c


#include <string.h>

#include <jni.h>        // JNI header provided by JDK

#include "locksmith.h"

#include "yada_yada_locksmith_Locksmith.h"

此外,构建命令需要只是


go build -o liblocksmith.so -buildmode=c-shared

没有在最后。locksmith.go


查看完整回答
反对 回复 2022-08-09
  • 1 回答
  • 0 关注
  • 181 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号