B4Alpha-Aft3r0mega / javacpp

Automatically exported from code.google.com/p/javacpp
GNU General Public License v2.0
0 stars 0 forks source link

Function pointer instances of the same type overwrite each other? #35

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
This is a bit of a funny problem and I am not exactly sure if I am doing 
something wrong or facing an actual JavaCPP bug, but I have boiled the issue 
down to a fairly simple code example which is attached to this issue.

The code basically defines a C++ class to which you can attach observers. When 
I create two separate instances of the same class and attach an individual 
observer instance to each one them, the first observer somehow gets overwritten 
by the first. This is only true for the Java version using JavaCPP, though, the 
C++ version works fine. My guess is now that this is a bug in the code 
generated by JavaCPP, but I couldn't figure it out.

Output of the example code:

java -cp javacpp.jar:. Stuff
Observer 2 - value changed: name -> Changed 2
Observer 2 - value changed: name -> Changed
./test
Observer 2 - value changed: name -> Changed 2
Observer 1 - value changed: name -> Changed

Note:

The Makefile was only tested on Mac OS X 10.8 by me.

Original issue reported on code.google.com by neoco...@googlemail.com on 5 Jul 2013 at 12:38

Attachments:

GoogleCodeExporter commented 8 years ago
Yes, that's a known limitation for C-style function pointers:
http://code.google.com/p/javacpp/source/browse/src/main/java/com/googlecode/java
cpp/Generator.java#1756

But this doesn't apply to the underlying "function objects" (aka "functors"), 
which we can use by annotating the parameters with @ByVal or @ByRef, i.e.:
    registerObserver(@ByVal Observer observer);

Does that work for your use case?

Original comment by samuel.a...@gmail.com on 7 Jul 2013 at 1:21

GoogleCodeExporter commented 8 years ago
Yep, works fine, thanks! Might be an item for a FAQ or something, I was pulling 
my hair out for days over it :).

Original comment by neoco...@googlemail.com on 8 Jul 2013 at 7:21

GoogleCodeExporter commented 8 years ago
This issue is as good as any :) But sure, more documentation is always welcome.

Original comment by samuel.a...@gmail.com on 8 Jul 2013 at 7:41

GoogleCodeExporter commented 8 years ago
BTW, that works only in C++. For C, the way to work around that at the moment 
is by declaring multiple allocate() methods, and use a different one for each 
of the instances of the FunctionPointer. In the case of a function in FFmpeg, 
for example:

    public static class Read_packet_Pointer_BytePointer_int extends FunctionPointer {
        static { Loader.load(); }
        protected native void allocate();
        protected native void allocate2();
        protected native void allocate3();
        protected native void allocate4();
        protected native void allocate5();
        protected native void allocate6();
        // etc
        public native int call(Pointer opaque, @Cast("uint8_t*") BytePointer buf, int buf_size);
    }

And then in the user's code (I think those could still be anonymous classes):

    public static class FirstStreamRead extends Read_packet_Pointer_BytePointer_int {
        FirstStreamRead() { allocate(); }
        public int call(Pointer opaque, BytePointer buf, int buf_size) {
            return 0;
        }
    }
    public static class SecondStreamRead extends Read_packet_Pointer_BytePointer_int {
        SecondStreamRead() { allocate2(); }
        public int call(Pointer opaque, BytePointer buf, int buf_size) {
            return 0;
        }
    }
    // etc

The Parser doesn't generate those, for now, but I guess it's something we could 
add... 

Original comment by samuel.a...@gmail.com on 21 Dec 2013 at 12:10