Доступ к структуре напрямую из C ++ из java кода - PullRequest
1 голос
/ 17 января 2020

Я новичок в javacpp Я знаю, java не имеет большого опыта в C ++. Это может быть один из очень простых вопросов, но я борюсь с этим. Как получить доступ к любому значению типа переменной, записанному в заголовке c ++, в java код, используя javacpp. Давайте рассмотрим пример:

Пример кода C ++ :

Существует функция, написанная на C ++, которая возвращает кадр видео ниже, это код для него и ожидает аргумент Struct

unsigned char *
Videodecode::getframe_data (void *ptr)
{
  GstSample *sample;
  GstBuffer *buffer;
  GstMapInfo map;
  GstCaps *caps;
  GstStructure *str;
  gint width, height;
  gstData *dataa = (gstData *) ptr;

  sample = gst_app_sink_pull_sample ((GstAppSink*)dataa->sink);

  if (sample != NULL) {

    buffer = gst_sample_get_buffer (sample);
    gst_buffer_map (buffer, &map, GST_MAP_READ);
    if (map.data != NULL) {
      caps = gst_sample_get_caps (sample);
      if (caps != NULL);
      str = gst_caps_get_structure (caps, 0);
      if (!gst_structure_get_int (str, "width", &width) ||
          !gst_structure_get_int (str, "height", &height)) {
        g_print ("No width/height available\n");
      }
      display_data = map.data;
      //displayImg = Mat (Size (width, height ), CV_8UC3, map.data);
 //   cvtColor (displayImg, displayImg, COLOR_YUV2BGR_YUY2);

      gst_buffer_unmap (buffer, &map);
      gst_buffer_unref (buffer);
    } else
      gst_sample_unref (sample);

  }
  else {

      //cout << "gstImageBuffer is NULL" << endl;
      return NULL;
  }
  //return displayImg.data;
  return display_data;
}

Ниже указана структура, которую необходимо передать в качестве аргумента

typedef struct gstData_t
{
  GstElement *pipeline;
  GstElement *source;
  GstElement *demux;
  GstElement *parser;
  GstElement *decoder;
  GstElement *convert;
  GstElement *capsfilter;
  GstElement *sink;
  GstElement *typefind;

} gstData;

Соответствующий java код, написанный для доступа к нему, приведен ниже:

import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;

import org.bytedeco.javacpp.FunctionPointer;
import org.bytedeco.javacpp.Loader;
import org.bytedeco.javacpp.Pointer;
import org.bytedeco.javacpp.annotation.Name;
import org.bytedeco.javacpp.annotation.NoOffset;
import org.bytedeco.javacpp.annotation.Platform;
import org.bytedeco.javacpp.annotation.Raw;
import org.bytedeco.javacpp.tools.Builder;
import org.bytedeco.javacpp.tools.ParserException;



@Platform(include = {"Videodecode.h",
                    }, 
includepath = {"/usr/include/gstreamer-1.0/","/usr/include/glib-2.0/","/usr/lib/x86_64-linux-gnu/glib-2.0/include/"},
//linkpath = {"/home/ign/git/JavaCppExample/src/main/resources/de/oltzen/javacppexample/"},
link = {"Videodecode"})

public class Videodecode {
    NativeVideodecode nda;
    static {

        Class c = Videodecode.class;

            Builder builder = null;
            try {
                builder = new Builder().classesOrPackages(c.getName());
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (NoClassDefFoundError e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            try {
                File[] outputFiles = builder.build();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (ParserException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            Loader.load(c);


//      Loader.load(); 

    }

    public Videodecode() {
        nda = new NativeVideodecode();
    }

    public Videodecode(String filename) {
        nda = new NativeVideodecode(filename);
    }

    public boolean filePathCpp(String str){ 
        return nda.filePathCpp(str);
    }

    public boolean settingValCpp(String str){   
        return nda.settingValCpp(str);
    }

    public boolean process_event (int event) {
        return nda.process_event(event);
    }

    public java.nio.ByteBuffer test1122 (String buffer) {       
        return nda.test1122(buffer);
    }

    public java.nio.ByteBuffer test112233 (String buffer) {     
        return nda.test1122(buffer);
    }

    public java.nio.ByteBuffer getframe_data(java.nio.ByteBuffer buffer){
        return nda.getframe_data(buffer);
    }

    public Pointer gstData(){
        return nda.gstData();
    }

    @Name("Videodecode")    
    public static class NativeVideodecode extends Pointer {
        static { 
            Loader.load();
        }

        public NativeVideodecode() {
            allocate();
        }

        public NativeVideodecode(String filename) {
            System.out.println("filename "+filename);
            allocate(filename);
        }

        public NativeVideodecode(Pointer p) {
            super(p);
        }

        private native void allocate(String filename);
        private native void allocate();
        private native boolean filePathCpp(String str);
        private native boolean settingValCpp(String str);
        private native boolean process_event(int event);
        private native java.nio.ByteBuffer test1122(String buffer);
        private native java.nio.ByteBuffer test112233(String buffer);
//      private native boolean test1122(byte[] buffer);
        private native java.nio.ByteBuffer getframe_data (java.nio.ByteBuffer buffer);
        @NoOffset private native Pointer gstData();
    }


}

Проблемы, с которыми я столкнулся:

  1. Как получить доступ к Struct из C ++ и передать его в качестве аргумента, используя java.
  2. Как получить доступ к данным кадра, которые не подписаны char *.

Подход, который я пытался выполнить.

  1. Чтобы получить доступ к Struct, я попытался использовать offsetof, но не уверен, как его использовать в javacpp.
  2. Для доступа к данным кадра я пытался использовать java .nio.ByteBuffer, но, похоже, он не работает должным образом.

При попытке скомпилировать код с помощью mvn clean install ниже ошибка срабатывает.

[INFO] --- javacpp:1.3:build (javacpp.compiler) @ projecustom ---
[INFO] Detected platform "linux-x86_64"
[INFO] Building for platform "linux-x86_64"
[WARNING] Could not load platform properties for class com.proje.decoder.connectorJavaCpp
[WARNING] Could not load platform properties for class com.proje.decoder.test1234
[INFO] Generating /home/ign/eclipse-workspace/projecustom/target/classes/com/proje/decoder/jniVideodecode.cpp
[INFO] Compiling /home/ign/eclipse-workspace/projecustom/target/classes/com/proje/decoder/linux-x86_64/libjniVideodecode.so
[INFO] g++ -I/usr/include/gstreamer-1.0/ -I/usr/include/glib-2.0/ -I/usr/lib/x86_64-linux-gnu/glib-2.0/include/ -I/usr/lib/jvm/java-8-openjdk-amd64/include -I/usr/lib/jvm/java-8-openjdk-amd64/include/linux /home/ign/eclipse-workspace/projecustom/target/classes/com/proje/decoder/jniVideodecode.cpp -march=x86-64 -m64 -O3 -s -Wl,-rpath,$ORIGIN/ -Wl,-z,noexecstack -Wl,-Bsymbolic -Wall -fPIC -shared -o libjniVideodecode.so -lVideodecode 
/home/ign/eclipse-workspace/projecustom/target/classes/com/proje/decoder/jniVideodecode.cpp: In function ‘_jobject* Java_com_proje_decoder_Videodecode_00024NativeVideodecode_gstData(JNIEnv*, jobject)’:
/home/ign/eclipse-workspace/projecustom/target/classes/com/proje/decoder/jniVideodecode.cpp:1532:21: error: ‘class Videodecode’ has no member named ‘gstData’
         rptr = ptr->gstData();

редактировать:

позвольте мне попытаться взять на себя Простой пример:

C ++ Код:

#include <stdio.h>

struct test
{
int a;
std::string b;
};

class Foo {
public:
    int n;
    int m=70;
    test tst;
//    tst.a=10;
//    tst.b="hi";
    Foo(int n) : n(n) { }
    virtual ~Foo() { }
    virtual void bar() {
        printf("Callback in C++ (n == %d)\n", n);
    }
};

void callback(Foo *foo) {
    foo->bar();
}

Можно ли написать приведенный ниже код модификации java для доступа к переменным a и b структуры

package com.ign.examples;

import org.bytedeco.javacpp.*;
import org.bytedeco.javacpp.annotation.*;

@Platform(include="Foo.h")
public class VirtualFoo1 {
    static { Loader.load(); }

    public static class Foo extends Pointer {
        static { Loader.load(); }
        public Foo(int n) { allocate(n); }
        private native void allocate(int n);

        @NoOffset public native int n(); public native Foo n(int n);
        @Virtual  public native void bar();
        public native int m();   public native void m(int m);
//        public native @Cast("int") int a(); public native Foo a(int a);
        public native Pointer tst(); public native void tst(Pointer tst);
    }

    public static native void callback(Foo foo);

    public static void main(String[] args) {
        Foo foo = new Foo(13);

        System.out.println(foo.m());

    }
}
...