0

我有以下代码:

public class TTM {

public interface WrapperDLL extends Library {
    WrapperDLL INSTANCE = (WrapperDLL) Native.loadLibrary("TransportRE", WrapperDLL.class);

    int TRE_send(int channel, Pointer data, int len);

}
public int Send (int channel, String data, int len) {
    WrapperDLL wdll = WrapperDLL.INSTANCE;

    Memory mem = new Memory(data.length()+1);
    mem.setString(0, data);
    int byteSent = wdll.TRE_send(channel_id, mem.getPointer(0), len);
    // at this (TRE_send) point the VM crashes !!!!

  return byteSent;
}

}

看看我试过的 JNA api:

public int Send (int channel, String data, int len) {
    WrapperDLL wdll = WrapperDLL.INSTANCE;

    Memory mem = new Memory(data.length()+1);
    mem.setString(0, data);
    int byteSent = wdll.TRE_send(channel_id, mem, len);

  return byteSent;
}

这次不会崩溃但不能正常工作(byteSent = 0!)

一些提示?

4

2 回答 2

1

您正在取消引用您的String,就好像它包含指针而不是字符数据一样。

Pointer.getPointer(0)尝试从给定的指针地址中提取指针值;您肯定希望像在第二个代码段中那样直接传递指针值。

JNA 允许您直接传递一个String值,自动将其转换为 C 字符串(以 NUL 结尾的字节数组)。但是,您的本机方法是否需要字符串尚不清楚;它可能需要一个特殊格式的字节缓冲区。

如果len打算作为您发送的缓冲区的长度,那么它应该是字符串的长度加一(或Memory您传递的大小)。

编辑

您暗示 DLL 始终转换为char *,在这种情况下,您应该简单地按String原样传递。如果您的 DLL 有时需要非 ASCII 数据,那么您应该传递Memory并使用它的成员函数来写入所需的数据。请注意,您可以使用不同的签名定义多个版本的 DLL,例如

  void send(String);
  void send(Pointer);
  void send(MyStructure);
于 2012-10-03T15:45:46.950 回答
0

我修好了!

int byteSent = wdll.TRE_send(channel_id, data.toCharArray(), len);

因为第二个参数是 void* 但在 dll 代码中,第一件事是将它转换为 char * 我使用了相同的类型,现在它可以工作了。

当然这不是一个“通用解决方案”,因为“TRE_send”需要一个 void* 类型......你怎么看?

再见

于 2012-10-04T08:26:23.223 回答