Arslan
Arslan

Reputation: 31

JNA return char*

how to work with Check type char*? (Check fill in function and contains text >500 characters or pointer on memory with text)

I have my_dll.dll. Description dll

int my_function(char* param1, struct answer* ans);

#pragma pack(1)
struct answer{
  int TType;                   //IN
  unsigned long Amount;   //IN
  char          Rcode   [2+1];  //OUT
  char          AMessage[16 ]; //OUT
  int           CType;              //OUT
  char*         Check;            //OUT
};

In Java I have code:

 public interface My_Dll extends Library {
        public static class answer extends Structure {
                    public static class ByReference extends answer 
                             implements Structure.ByReference {}

              public int  TType      = 0;                   
              public int  Amount     = 0;        
              public byte Rcode[]    = new byte[3]; //OUT: 
              public byte AMessage[] = new byte[16]; //OUT: 
              public int  CType      = 0;         //OUT: 
              public ??? Check;         //OUT: 
              protected List getFieldOrder() {
                      return Arrays.asList(new String[] {"TType", "Amount", 
                             "Rcode","AMessage", "CType","Check"});
              }
        }
        public int my_function(byte track2[], answer.ByReference ans);
  }

  public static void Start() {
      My_Dll test_dll = (My_Dll) Native.loadLibrary("my_dll", My_Dll.class);
      My_Dll.answer.ByReference aa = new My_Dll.answer.ByReference();
      //  In
      aa.Amount = 100;
      aa.TType =3;

      int result = test_dll.my_function(null,aa);
      //  OUT
      System.out.println("Result: "  + result);
      System.out.println("Rcode: "  + new String(aa.Rcode));
      System.out.println("Amessage: " + new String(aa.AMessage));
}

Upvotes: 1

Views: 2471

Answers (2)

technomage
technomage

Reputation: 10069

Your Check field must be of pointer type. If you declare it as Pointer, you can use Pointer.getString(0) to extract the String value.

If it is up to the caller to allocate the memory, you can use com.sun.jna.Memory to initialize it; if not, you will need to release the memory returned in the struct to avoid a leak.

Upvotes: 1

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285403

One thing I've tried is to use a pre-constructed array of byte, and then use Native.toString(...) to convert it to a Java String. For example,

byte[] windowText = new byte[SOME_CONSTANT];
user32.GetWindowTextA(hWnd, windowText, SOME_CONSTANT);
String wText = Native.toString(windowText).trim();

In the code above, 512 worked well as my SOME_CONSTANT, but you will probably need to use a larger constant.

Upvotes: 1

Related Questions