GithubHelp home page GithubHelp logo

Comments (25)

saudet avatar saudet commented on June 10, 2024

There's a discussion about that at issue #22. Let me know if that doesn't answer the question.

from javacpp.

saudet avatar saudet commented on June 10, 2024

Ah same guy, so I guess it doesn't answer your question. So, what is the question? Could you provide more details about what steps you are taking, what errors you are getting, etc? Thanks

from javacpp.

phanthanhliem avatar phanthanhliem commented on June 10, 2024

Hi Saudet,

Sorry for my incomprehensible question.
The problem is when I used typedef like this:

typedef std::vector<double*>        Vector_p_Double;
struct structTimeSeriesResults
{   
    Vector_p_Double         vpd_result;
...
}

There is an error when I compile:
image
which tells that javacpp cannot convert from Vector_p_Double to std::vector<double *,std::allocator<_Ty>> *. It seems that javacpp does not understand the new type Vector_p_Double defined by the typedef command.

Without using typedef std::vector<double*> Vector_p_Double;, or more exactly using directly std::vector<double*> it works fine like in #22

So the question is how could I use typedef std::vector<double*> Vector_p_Double;?
Hope that you understand my question now.

Thank you for your help.
Thanh Liem.

from javacpp.

saudet avatar saudet commented on June 10, 2024

Ok... Would you have a complete self-contained example that I could try to run here? Thanks!

from javacpp.

phanthanhliem avatar phanthanhliem commented on June 10, 2024

Hi Samuel,
I've send a self contained example to your email.
Thanks for your help.

from javacpp.

saudet avatar saudet commented on June 10, 2024

I mean some small code example, of less than 100 lines...

from javacpp.

phanthanhliem avatar phanthanhliem commented on June 10, 2024

Hi Samuel

This is the header spider.h

#ifndef SPIDER_H
#define SPIDER_H

#ifdef SPIDER_CPP_LIBRARY
#define SPIDERDLL_API __declspec(dllexport)
#else
#define SPIDERDLL_API __declspec(dllimport)
#endif

namespace Spider_CPP {
class spider {
public:
    SPIDERDLL_API spider();
    SPIDERDLL_API Struct_Simulation_Results * runSingleSimulation(std::string Simulator_Parameters_Full_File_Name);
}
}

typedef std::vector<double>         Vector_Double;
struct Struct_Simulation_Results
{
    Simulation_Flag         Flag;
    structTimeSeriesResults * s_timeSeriesResults;
    Vector_Double           vd_Indicators;    
};

enum Simulation_Flag
{
    Simulation_OK = 0,
    Initialisation_Failed = 1,
    Simulation_Failed = 2
};

typedef std::vector<double*>        Vector_p_Double;
struct structTimeSeriesResults
{
    Vector_p_Double  *     vpd_result;    
    double*                 p_time;
    int                     nbPoints;
};

And the javacpp source code, testspiderdll.cpp

@Platform(include={"spider.h"}, link="SPIDER")

@Namespace("Spider_CPP")
public class testspidercpp {
    public static class spider extends Pointer {
        static { 
            System.loadLibrary("jnitestspidercpp");             
        }
        public spider() { allocate(); }     
        private native void allocate();
        public native Struct_Simulation_Results runSingleSimulation(@StdString String Simulator_Parameters_Full_File_Name);
    }

    @Namespace("")  
    public static class Struct_Simulation_Results extends Pointer {
        static { Loader.load(); }

        public Struct_Simulation_Results () { allocate(); }     
        private native void allocate();

        public native @Cast("Simulation_Flag") int Flag(); public native Struct_Simulation_Results Flag(@Cast("Simulation_Flag") int Flag); 

        public native structTimeSeriesResults s_timeSeriesResults(); public native Struct_Simulation_Results s_timeSeriesResults(structTimeSeriesResults s_timeSeriesResults);

        public native @StdVector DoublePointer vd_Indicators(); public native Struct_Simulation_Results vd_Indicators(@StdVector DoublePointer vd_Indicators);
    }

    @Namespace("")
    public static enum Simulation_Flag {
        Simulation_OK(0), Initialisation_Failed(1), Simulation_Failed(2);
        private int value;
        private Simulation_Flag(int value) {
            this.value = value;
        }

        public static Simulation_Flag fromInt(int v) {
            return Simulation_Flag.values()[v];
        } 

        public Simulation_Flag getType() {
            return Simulation_Flag.fromInt(nativeGetType());
        }

        private native @Name("getType") int nativeGetType();
    }

    @Namespace("")
    public static class structTimeSeriesResults extends Pointer {
        static { Loader.load(); }
        public structTimeSeriesResults () { allocate(); }       
        private native void allocate();

        public native VectorDoublePointer vpd_result(); public native structTimeSeriesResults vpd_result(VectorDoublePointer vpd_result);
        public native DoublePointer p_time();   public native structTimeSeriesResults p_time(DoublePointer p_time);
        public native int nbPoints();   public native structTimeSeriesResults nbPoints(int nbPoints);       
    }

    @Namespace("")
        // std:::vector<double*> in the line below works fine 
    //@Name("std::vector<double*>") public static class VectorDoublePointer extends Pointer {
    @Name("Vector_p_Double") public static class VectorDoublePointer extends Pointer {
        static { Loader.load(); }

        public VectorDoublePointer(Pointer p) { super(p); }
        public VectorDoublePointer(DoublePointer ... array) { this(array.length); put(array); }
        public VectorDoublePointer()       { allocate();  }
        public VectorDoublePointer(long n) { allocate(n); }
        private native void allocate();
        private native void allocate(@Cast("size_t") long n);
        public native @Name("operator=") @ByRef VectorDoublePointer put(@ByRef VectorDoublePointer x);

        public native long size();
        public native void resize(@Cast("size_t") long n);

        @Index public native @Cast("double*") DoublePointer get(@Cast("size_t") long i);
        public native VectorDoublePointer put(@Cast("size_t") long i, DoublePointer value);

        public VectorDoublePointer put(DoublePointer ... array) {
            if (size() != array.length) { resize(array.length); }
            for (int i = 0; i < array.length; i++) {
                put(i, array[i]);
            }
            return this;
        }
    }   

    public static void main(String[] args) {
        spider dllInstance = new spider();      
        System.out.println("spider.dll is successfully loading!!\n");
        String simulator_param_fullpath = "C:\\Users\\tp242786\\MyPostdoc-INES\\SPIDER\\SPIDER Qt5.4.2_MSVC2013_64bit\\Plant_And_Controls.parameters";
        dllInstance.runSingleSimulation(simulator_param_fullpath);
    }   
}

So how could i write the javacpp code for using:

typedef std::vector<double>         Vector_Double;
typedef std::vector<double*>        Vector_p_Double;

Hope that these source codes is enough for you to reproduce a running example.
Thanks for your support.

from javacpp.

saudet avatar saudet commented on June 10, 2024

Vector_Double and Vector_p_Double are declared in the Spider_CPP namespace, so their effective types are Spider_CPP::Vector_Double and Spider_CPP::Vector_p_Double, respectively. They are NOT Vector_Double and Vector_p_Double.

from javacpp.

phanthanhliem avatar phanthanhliem commented on June 10, 2024

Hi Samuel,

No, Vector_Double and Vector_p_Double are NOT declared in the Spider_CPP namespace.
In fact, Spider_CPP namespace contains just this:

namespace Spider_CPP {
  class spider {
     public:
        SPIDERDLL_API spider();
        SPIDERDLL_API Struct_Simulation_Results * runSingleSimulation(std::string     Simulator_Parameters_Full_File_Name);
  }
}

I put @Namespace("") to escape the Spider_CPP namespace,
and this works well for other structs.
So do you have an example with the typedef structure?

Thanks and
best regards.

from javacpp.

phanthanhliem avatar phanthanhliem commented on June 10, 2024

Hi Samuel,

It's ok now, in the spider.h, I need to declare like this

Vector_p_Double       * vpd_result;

instead of

Vector_p_Double       vpd_result;

So, vpd_result must be declared like a pointer, which is compatible
with the javacpp source code:

@Name("Vector_p_Double") public static class VectorDoublePointer extends Pointer { ...}

I have one more question, if I don't want to use the pointer * in C++,
so I got ``Vector_p_Double vpd_result;`.
How do I define the class VectorDoublePointer in javacpp now?

Thanks for your support.

from javacpp.

saudet avatar saudet commented on June 10, 2024

I see, well I just tried your example here and after fixing a few issues with your C++ code, it works just fine with Vector_p_Double. So, I still don't understand what the issue is. Please provide some sample code so that I can reproduce the issue here. Thank you.

from javacpp.

phanthanhliem avatar phanthanhliem commented on June 10, 2024

Hi Samuel,

Thanks for your patient. I will reexplain the problem :

With the definition of VectorDoublePointer in testspidercpp.java,

@Name("Vector_p_Double") public static class VectorDoublePointer extends Pointer { ...}

you could only declare Vector_p_Double * vpd_result; in C++ because VectorDoublePointer extends the class Pointer. Otherwise, a definition without pointer *, for example Vector_p_Double vpd_result; will cause an error in the compilation.

However, the C++ code in my project is developped by some one else, so in this case, I have to insert the pointer notation *, for example, before all the struct defined in the C++ module.

- Struct_Simulation_Results        *       spider::runSingleSimulation(std::string Simulator_Parameters_Full_File_Name)
- Struct_Simulation_Results   *    s_simulationResults
- Vector_p_Double       * vpd_result; 
- ...

So the question is how could I redefine the class VectorDoublePointer or structTimeSeriesResult
to remove the usage of the pointer * in the C++ side. Or Which predefined class should I extend instead of Pointer. If this is possible, do you have an example? In javacpp-presets, most classes extend Pointer.

Hope that my question is clearer now.
Thanks for your help.

from javacpp.

saudet avatar saudet commented on June 10, 2024

Ah I see. Because it's just a typedef we can simply use the original name std::vector<double*>. They are just synonyms!

from javacpp.

phanthanhliem avatar phanthanhliem commented on June 10, 2024

Hi Samuel,

The problem of using Vector_p_Double or std::vector<doubble*> is OK now.
In fact, using one of these two definitions is OK, we got the same result:

@Name("Vector_p_Double") public static class VectorDoublePointer extends Pointer { ...}
@Name("std::vector<double*>") public static class VectorDoublePointer extends Pointer { ...}

However in C++ side, I have to declare a pointer (ex: Vector_p_Double * vdp or std::vector<double*> * vdp), because the class VectorDoublePointer extends Pointer class.
I can not declare a variable without pointer like this Vector_p_Double vdp or std::vector<double*> vdp.

My problem is: I want to use a var without pointer in C++ side (Vector_p_Double vdp or std::vector<double*> vdp), and how could I change correspondingly the definition of class in javacpp. In this case, the old definition of VectorDoublePointer which extends Pointer doesn't work anymore, there will be always a compilation error.

Hope that it is clearer for you, Samuel.

from javacpp.

saudet avatar saudet commented on June 10, 2024

For something like this:

typedef std::vector<double*>*  Vector_p_Double;
Vector_p_Double vdp();

Of course we can do something like this:

@Name("std::vector<double*>") public static class VectorDoublePointer extends Pointer { ... }
public static native VectorDoublePointer vdp();

That works just fine, no problem. So, your question must be about something else.

from javacpp.

phanthanhliem avatar phanthanhliem commented on June 10, 2024

Hi Samuel,

Sorry, :D, I don't know how to explain my prob clearer.
I need to use this declaration in C++:
typedef std::vector<double*> Vector_p_Double;

But the code in javacpp which I found in the preset
@Name("std::vector<double*>") public static class VectorDoublePointer extends Pointer { ... }
just support some thing like this:
typedef std::vector<double*> * Vector_p_Double;

How could I modify the class definition in javacpp code? For example, by removing extends Pointer, we need to change many things in the body ?

from javacpp.

saudet avatar saudet commented on June 10, 2024

typedef has no effect on Pointer, or vice-versa: the issue is something else...

from javacpp.

phanthanhliem avatar phanthanhliem commented on June 10, 2024

Hi Samuel,
Yes, the prob is not typedef.
But between
typedef std::vector<double*> Vector_p_Double;
and
typedef std::vector<double*> * Vector_p_Double;
The difference here is Vector_p_Double vs * Vector_p_Double

The second one is ok as we discussed, but how about the first one?
Thanks for your help.

from javacpp.

saudet avatar saudet commented on June 10, 2024

I'm afraid I still don't understand the issue.

Have you tried to use the Parser instead?

from javacpp.

phanthanhliem avatar phanthanhliem commented on June 10, 2024

Yes, i've tried to use the Parser. The following sourceds are the content of Stuff.h and Stuff.java (generated from StuffConfig).

Stuff.h
std::vector<unsigned char> foo();
std::vector<double*> vpd_result;
std::vector<double*> * vpd_result_pointer;
Stuff.java
// Parsed from Stuff.h
// #include <vector> 

public static native @Cast("unsigned char*") @StdVector BytePointer foo();
public static native @Cast("double**") @StdVector PointerPointer vpd_result(); public static native void vpd_result(PointerPointer vpd_result);
public static native @Cast("double**") @StdVector PointerPointer vpd_result_pointer(); public static native void vpd_result_pointer(PointerPointer vpd_result_pointer);

I didn't understand why there is no difference between vpd_result & vpd_result_pointer in Stuff.java, although in Stuff.h, they are not the same thing.

from javacpp.

saudet avatar saudet commented on June 10, 2024

The @StdVector adapter just copies the whole vector and returns the copy. It doesn't matter if the original vector is returned by pointer or by value.

from javacpp.

phanthanhliem avatar phanthanhliem commented on June 10, 2024

Hi Samuel,

I still couldn't figure out how does it work.
I've tried this example this works well.

stuff.h
std::vector<std::string>           vd_Indicators;
stuff.java
public native @StdVector DoublePointer vd_Indicators(); 
public native Struct_Simulation_Results vd_Indicators(@StdVector DoublePointer vd_Indicators);

However if I changed the definition in stuff.h

stuff.h
//std::vector<std::string>           vd_Indicators;
std::vector<std::string>          * vd_Indicators = new std::vector<std::string>();

It causes immediately a crash in the java virtual machine.
I assume that in this case the Java definition @StdVector DoublePointer vd_Indicators() could not be used with std::vector<std::string> * vd_Indicators.

So I don't understand your phrase Samuel. A pointer or a value is really a problem here.

from javacpp.

phanthanhliem avatar phanthanhliem commented on June 10, 2024

Another example,

stuff.h
std::vector<std::string>  *  vs_labels = new std::vector<std::string>();
stuff.java
@Name("std::vector<std::string>") public static class StringVector extends Pointer { }

Here I retakes the definition in open_cv.core.
There no problems with the pointer std::vector<std::string> * vs_labels.

How ever if I use a value instead

stuff.h
//std::vector<std::string>  *  vs_labels = new std::vector<std::string>();
std::vector<std::string>  vs_labels;

then the JVM is crashed as the previous example.

Somes observations here:

  • the java definition of a class can't not be used for both pointer and value.
  • @stdvector DoublePointer can not be used for a pointer in C++
  • Class StringVector can not be used for a value in C++.

from javacpp.

saudet avatar saudet commented on June 10, 2024

You're right that there was some native support missing for vector pointers to work with @StdVector. It should work with the changes from the latest commit: f61ac32
Let me know! Thanks

from javacpp.

phanthanhliem avatar phanthanhliem commented on June 10, 2024

Hi Samuel,

But it's ok now, by placing a @byval before StringVector in the class (struct) that use this StringVector, for ex:

public native @ByVal VectorStringPointer vs_labels();
public native structTimeSeriesResults vs_labels(@ByVal VectorStringPointer vs_labels);

I understand JavaCPP better now.
Thanks for your help.

from javacpp.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.