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

我正在尝试通过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 __cplusplus

extern "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);


慕码人2483693
浏览 182回答 1
1回答

心有法竹

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>&nbsp; &nbsp; &nbsp; &nbsp; // JNI header provided by JDK#include "locksmith.h"#include "yada_yada_locksmith_Locksmith.h"此外,构建命令需要只是go build -o liblocksmith.so -buildmode=c-shared没有在最后。locksmith.go
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go