我是JNA编程的新手,我想完成的任务是:
C ++库公开了将缓冲区“放入”文件并“查找”缓冲区的功能。我为这个库编译了一个共享对象(.so),头文件提供了“extern”C“”下的函数定义,使其对编译器友好。
测试java程序以访问缓冲区。
代码如下所示:
C / C ++代码:
extern "C"
{
int get(int length, char *buffer);
}
#include <iostream>
#include <string.h>
int get(int length, char *buffer)
{
char *newBuff = new char[length];
for (int i = 0; i < length; ++i)
{
newBuff[i] = 'a';
}
memcpy(newBuff, buffer, length);
delete newBuffer;
return length;
}
java代码:
import com.sun.jna.Library;
import com.sun.jna.Memory;
import com.sun.jna.Native;
public class TestJna
{
public static interface TestNative extends Library
{
int get(int length, Memory buffer);
}
private static final TestNative lib_ = (TestNative)Native.loadLibrary("libsample.so", TestNative.class);
public static void main(String[] args)
{
int length = 1024;
Memory buffer = new Memory(length);
int ret = lib_.get(length, buffer);
System.out.println("ret:" + ret + ":buffer:" + buffer.toString());
}
}
在运行程序时,我在调用“lib.get()”方法时得到以下错误消息:
线程“main”中的异常java.lang.UnsatisfiedLinkError:查找函数'get'时出错:dlsym(0x7f8d08d1e7d0,get):找不到符号
答案 0 :(得分:1)
导出的符号(根据nm
)被破坏了。除了声明之外,您还需要在函数定义之前添加extern "C"
,即
extern "C" get(int length, char* buffer) {
...
}
您使用的第一个extern "C"
语法通常用于头文件中的声明组。您还必须明确取消定义。
答案 1 :(得分:0)
我能够通过修改代码使其工作如下:
public static interface TestNative extends Library
{
int get(int length, Pointer buffer);
}
指针是通过以下方式获得的:
Pointer bfPtr = Native.getDirectBufferPointer(buffer); // buffer points to ByteBuffer allocated as direct NIO buffer.