将函数指针的C结构转换为JNA代码

时间:2017-09-18 04:50:26

标签: java c++ c

// 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。

1 个答案:

答案 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

输出看起来像我期待的那样..

enter image description here

我真诚地希望这会对你有所帮助。