gpt4 book ai didi

java - JNI 使用。 "symbol lookup error"

转载 作者:太空狗 更新时间:2023-10-29 23:05:57 26 4
gpt4 key购买 nike

我尝试将 md5 共享库与 Java native 接口(interface)一起使用。 Here你可以检查来源。该库太大,无法准备与 JNI 一起使用。所以我想使用一个简单的附件库进行链接。在测试时构建这个库后,我得到了这个输出:

  java: symbol lookup error: ./libMd5bridge.so: undefined symbol: _Z3md5Ss

我尝试执行 LD_PRELOAD 但没有结果。所以在这里我一步一步地发布我的每一个 Action 。

1) 我可以用非常简单的 C++ 代码调用我的 md5 库:

#include <iostream>
#include "md5.h"

int main(int argc, char* argv[]) {
std::string passedValue;
for(int i = 1; i < argc; i++)
passedValue += argv[i];
std::cout << "MD5 sum is: " << md5(passedValue) <<std::endl;
return 0;
}

我将附件库命名为 Md5bridge。所以在下一个上下文中我会这样调用它。

2)Md5Bridge.java

public class Md5bridge{
native public void MD5SUM(String[] passedValue);
}

3)获取Md5bridge头文件:

javac Md5Bridge.java && javah Md5Bridge

Md5bridge.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Md5bridge */

#ifndef _Included_Md5bridge
#define _Included_Md5bridge
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Md5bridge
* Method: MD5SUM
* Signature: ([Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_Md5bridge_MD5SUM
(JNIEnv *, jobject, jobjectArray);

#ifdef __cplusplus
}
#endif
#endif

4) 准备从第一步到使用 jni 的代码:

#include <iostream>
#include "md5.h"
#include "Md5bridge.h"
JNIEXPORT void JNICALL Java_Md5bridge_MD5SUM
(JNIEnv *, jobject, jobjectArray) {

std::string passedValue;
md5(passedValue);
}

5) 编译为共享库:

g++ -shared -fPIC -I /opt/jdk1.6.0_45/include/ -I /opt/jdk1.6.0_45/include/linux -o libMd5bridge.so Md5bridge.cpp

6)准备一个简单的java程序来检查这个库:

   public class Main{
static{
System.loadLibrary("Md5bridge");
}
public static void main(String[] passedValue){
new Md5bridge().MD5SUM(passedValue);
}
}

这个程序是用 javac 编译的,运行时出错(我在这篇文章的开头写了一个):

java: symbol lookup error: ./libMd5bridge.so: undefined symbol: _Z3md5Ss

我不熟悉 java,我认为我在其中一个步骤中做错了什么。有什么想法吗?

更新:添加 extern "C"{} md5 头文件后(感谢 Chris Stratton )我得到了这个输出:

java: symbol lookup error: /home/andrey/Desktop/md5LIB/libMd5bridge.so: undefined symbol: md5

它看起来像是丢失了指向 libmd5.so 的链接。

$ ldd libMd5bridge.so 
linux-vdso.so.1 => (0x00007fff38666000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007f2dfde3a000)
libm.so.6 => /lib/libm.so.6 (0x00007f2dfdbb7000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00007f2dfd99f000)
libc.so.6 => /lib/libc.so.6 (0x00007f2dfd619000)
/lib64/ld-linux-x86-64.so.2 (0x00007f2dfe36b000)

如何链接两个库?

最佳答案

您的 C 实现必须如下所示:

#include <iostream>
#include "md5.h"
#include "Md5bridge.h"
#ifdef __cplusplus
extern "C" {//pay attention to this!
#endif
JNIEXPORT void JNICALL Java_Md5bridge_MD5SUM
(JNIEnv *, jobject, jobjectArray) {

std::string passedValue;
md5(passedValue);
}
#ifdef __cplusplus
} //pay attention to this
#endif 

但更好!使用已经在 J​​DK 中实现的原始 md5

这是我的 java 代码的快照:

public class MD5Converter {

private final static String ALGORITHM = "MD5";
private final static String ENCODING = "UTF-8";

public static String encryptToMd5(String normal) {
MessageDigest digest;
try {
digest = java.security.MessageDigest.getInstance(ALGORITHM);
digest.reset();
digest.update(normal.getBytes(ENCODING));
byte[] hash = digest.digest();
return byteToHex(hash); //This is on you res to implement this
} catch (NoSuchAlgorithmException e) {
final String err = "No such digest algorithm \"" + ALGORITHM + "\"";
log.fatal(err, e);
throw new IllegalStateException(err, e);
} catch (UnsupportedEncodingException e) {
final String err = "Unsupported encoding \"" + ENCODING + "\"";
log.fatal(err, e);
throw new IllegalStateException(err, e);
}
}
}

关于java - JNI 使用。 "symbol lookup error",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17322885/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com