4

I have a C++ library that uses a struct which contains a vector. I am having some difficulty determining the correct way to access this from Java via JNA.

My C++ structure:

#include <vector> struct topic { char* src_id; char* dest_id; int32_t num; std::vector<char*> names; }; 

My Java class:

public final class Topic extends Structure { public String src_id; public String dest_id; public int num; public String[] names; // This doesn't work public Topic() { } @Override protected List<String> getFieldOrder() { return Arrays.asList(new String[] { "src_id", "dest_id", "num", "names" }); } } 
8
  • Maybe this helps? I am sadly not really familiar with c++ Commented Feb 19, 2019 at 13:12
  • Thank you but this doesn't work for me. I need to make it work just with JNA. Commented Feb 19, 2019 at 13:29
  • Well another thing i noticed is that you use a Vector in c++ but an array in java, what happens when you use an array in c++ too? Commented Feb 19, 2019 at 13:34
  • @Lino It shouldn't matter because vector is a managed array. It just knows additional info like size and has additional capabilities. But when it comes to accessing memory contents both are similar Commented Feb 19, 2019 at 13:39
  • @SolidMercury So it's like an ArrayList in java, my thought behind the array thing was, that I am not entirely sure, that JNI will know how to directly convert from a std::vector to an array. Just a speculation though Commented Feb 19, 2019 at 13:42

2 Answers 2

2

This solution worked for me:

package com.example; import java.util.Arrays; import java.util.List; import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.Pointer; import com.sun.jna.StringArray; import com.sun.jna.Structure; public class Example { public interface CLibrary extends Library { public static class Topic extends Structure { public static class ByReference extends Topic implements Structure.ByReference { } public String src_id; public String dest_id; public int num; public int numVals; public Pointer names; // char** @Override protected List<String> getFieldOrder() { return Arrays.asList(new String[] { "src_id", "dest_id", "num", "numVals", "names" }); } } public void sendTopic(Topic.ByReference pVal); } public static void main(String[] args) { final CLibrary clib = Native.loadLibrary("example.dll", CLibrary.class); final String[] myArray = new String[5]; myArray[0] = "one"; myArray[1] = "two"; myArray[2] = "three"; myArray[3] = "four"; myArray[4] = "five"; CLibrary.Topic.ByReference ref = new CLibrary.Topic.ByReference(); ref.numVals = 5; ref.names = new StringArray(myArray); clib.sendTopic(ref); } } 
Sign up to request clarification or add additional context in comments.

1 Comment

Does that mean my suggestion over comment helped you?
0

You can use Pointer and pass StringArray using public StringArray(String[] strings) as mentioned here

public String src_id; public String dest_id; public int num; public Pointer names; String[] namesArray= new String[2]; //Assign two names to namesArray //Construct StringArray with namesArray and pass it to Pointer names = new StringArray(namesArray); 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.