// original c code
struct callback {
void (*recv_msg_)(const char * msg, int type, unsigned int len);
void (*connected_)(void *cs);
void (*disconnected_)(void *cs);
};
void recv_msg(const char *msg, int type, unsigned int len)
{
// some code
//......
}
void connected(void *s)
{
// some code
//......
}
void disconnected(void *s)
{
// some code
//......
}
struct callback cb;
cb.recv_msg_ = recv_msg;
cb.connected_ = connected;
cb.disconnected = disconnected;
init("127.0.0.1", 5672, &cb);
// C code end
////////////////////////////////////////////////////////////////////////
// THE JNA code
interface RecvMsg extends Callback {
void invoke(String msg, int type, int con_len);
}
interface CbConnected extends Callback {
void invoke(Pointer ctx);
}
interface CbDisconnected extends Callback {
void invoke(Pointer ctx);
}
class RecvMsgImpl implements RecvMsg {
@Override
public void invoke(String msg, int type, int len) {
System.out.println("recv msg: " + msg);
}
}
class CbConnectedImpl implements CbConnected {
@Override
public void invoke(Pointer ctx) {
System.out.println("connected.");
}
}
class CbDisconnectedImpl implements CbDisconnected {
@Override
public void invoke(Pointer ctx) {
System.out.println("diconnected.");
}
}
public class MyCallBack extends Structure {
public RecvMsg recv_msg_;
public CbConnected cb_connected_;
public CbDisconnected cb_disconnected_;
@Override
protected List getFieldOrder() {
return Arrays.asList(new String[] {"recv_msg_", "cb_connected_", "cb_disconnected_"});
}
}
MyCallBack cb = new MyCallBack();
cb.recv_msg_ = new RecvMsgImpl();
cb.cb_connected_ = new CbConnectedImpl();
cb.cb_disconnected_ = new CbDisconnectedImpl();
Xxx xxx = (Xxx) Native.loadLibrary("***", Xxx.class);
xxx.init("127.0.0.1", 5672, cb);
// Java code end
////////////////////////////////////////////////////////////////////
我运行java代码,得到这样的异常:
Exception in thread "main" java.lang.IllegalArgumentException: Structure field "cb_connected_" was declared as interface DLLTest.CbConnected, which is not supported within a Structure
at com.sun.jna.Structure.writeField(Structure.java:808)
at com.sun.jna.Structure.write(Structure.java:718)
at com.sun.jna.Structure.autoWrite(Structure.java:1923)
at com.sun.jna.Function.convertArgument(Function.java:505)
at com.sun.jna.Function.invoke(Function.java:297)
at com.sun.jna.Library$Handler.invoke(Library.java:212)
at com.sun.proxy.$Proxy1.init(Unknown Source)
at DLLTest.Tester.main(Tester.java:55)
请告诉我如何使用JNA将其翻译为java。
答案 0 :(得分:0)
这是我对jna库的测试。
我认为你必须找到与我的不同之处。
我制作了自己的代码,因为你没有向我展示完整的源代码。
我的开发环境是带有msys2的mingw64和带有java(1.8)的eclipse(氧气)
以下是一些更多细节。
Gcc版
Using built-in specs.
COLLECT_GCC=C:\DEV\COMP\msys32\mingw64\bin\gcc.exe
COLLECT_LTO_WRAPPER=C:/DEV/COMP/msys32/mingw64/bin/../lib/gcc/x86_64-w64-
mingw32/6.3.0/lto-wrapper.exe
Target: x86_64-w64-mingw32
Configured with: .....skip
Thread model: posix
gcc version 6.3.0 (Rev1, Built by MSYS2 project)
Java信息
java.class.version::52.0
sun.management.compiler::HotSpot 64-Bit Tiered Compilers
sun.arch.data.model::64
sun.desktop::windows
sun.cpu.isalist::amd64
首先,您的JnaTest类的完整代码。
package stackoverflow;
import java.util.Arrays;
import java.util.List;
import com.sun.jna.Callback;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
public class JnaTest {
public interface JnaInf extends Library {
public void init(String val, int port, MyCallBack cb);
}
public static void main(String[] args) {
MyCallBack cb = new MyCallBack();
cb.recv_msg_ = new RecvMsgImpl();
cb.cb_connected_ = new CbConnectedImpl();
cb.cb_disconnected_ = new CbDisconnectedImpl();
System.load("C:\\DEV\\COMP\\msys32\\home\\stackoverflow\\jna_inf.dll");
JnaInf xxx = (JnaInf) Native.loadLibrary("jna_inf", JnaInf.class);
xxx.init("127.0.0.1", 5672, cb);
}
interface RecvMsg extends Callback {
void invoke(String msg, int type, int con_len);
}
interface CbConnected extends Callback {
void invoke(Pointer ctx);
}
interface CbDisconnected extends Callback {
void invoke(Pointer ctx);
}
static class RecvMsgImpl implements RecvMsg {
@Override
public void invoke(String msg, int type, int len) {
System.out.println("recv msg: " + msg);
System.out.println("type: " + type);
System.out.println("len: " + len);
}
}
static class CbConnectedImpl implements CbConnected {
@Override
public void invoke(Pointer ctx) {
System.out.println("connected.");
}
}
static class CbDisconnectedImpl implements CbDisconnected {
@Override
public void invoke(Pointer ctx) {
System.out.println("diconnected.");
}
}
public static class MyCallBack extends Structure {
public RecvMsg recv_msg_;
public CbConnected cb_connected_;
public CbDisconnected cb_disconnected_;
@Override
protected List getFieldOrder() {
return Arrays.asList(new String[] { "recv_msg_", "cb_connected_", "cb_disconnected_" });
}
}
}
然后,c源代码名称jna_info.c如下,
struct callback {
void (*recv_msg_)(const char * msg, int type, unsigned int len);
void (*connected_)(void *cs);
void (*disconnected_)(void *cs);
};
void recv_msg(const char *msg, int type, unsigned int len)
{
// some code
//......
}
void connected(void *s)
{
// some code
//......
return;
}
void disconnected(void *s)
{
// some code
//......
return;
}
void init(const char *msg, int type, struct callback *mycallback)
{
mycallback->recv_msg_("123", 22, 3);
mycallback->connected_("123");
return;
}
编译c源代码
gcc -c jna_inf.c
gcc -shared -o jna_inf.dll jna_inf.o
输出看起来像我期待的那样..
我真诚地希望这会对你有所帮助。