I come across a piece of
C++ code using interface
that trying to wrap but do not fully understand. I am getting cannot instantiate abstract class
error during compilation of JNI C++ code. Sorry for long post,
the description requires some background. This the continued
saga of trying to wrap the Basler Pylon library. At this point I
can connect to a camera and capture images, but cannot control
camera parameters.
I have an assignment in C++ that I would like to do in Java too.
camera.MaxNumBuffer = 5
I have the camera
class wrapped. The issue is with MaxNumBuffer.
It is defined in C++ as:
GenApi::IInteger &MaxNumBuffer
IInteger
is defined as:
interface GENAPI_DECL_ABSTRACT IInteger : virtual public IValue
{
virtual IInteger& operator=(int64_t Value) = 0;
...
};
All of its methods are
undefined, = 0.
There is also another class:
template <class T, class I=T>
class CIntegerRefT : public CValueRefT<T, I>
{
typedef CValueRefT<T, I> ref;
public:
virtual IInteger& operator=(int64_t Value)
{
...
}
...
};
Note that assignment
operator is actually defined (unlike in IInteger).
I assume that this is the one used in camera.MaxNumBuffer = 5.
Just to double check I extracted typeid:
cout << "name: " << typeid(camera.MaxNumBuffer).name() <<
endl;
name: class GenApi::CIntegerRefT<struct GenApi::IInteger,struct GenApi::IInteger>
There is also
typedef CIntegerRefT<IInteger> CIntegerRef
So to generate wrapper
for CIntegerRef
I added to Java preset:
new Info("GenApi::CIntegerRefT<GenApi::IInteger,GenApi::IInteger>").pointerTypes("CIntegerRef").define()
That resulted in compilable Java code, but failed at compilation of JNI code:
: error C2259: 'GenApi::CValueRefT<T,I>' : cannot instantiate abstract class
with
[
T=GenApi::IInteger
, I=GenApi::IInteger
]
due to following members:
'GenApi::IInteger &GenApi::IInteger::operator =(int64_t)' : is abstract
C:/Program Files/Basler/pylon 4/genicam/library/cpp/include/GenApi/IInteger.h(61) : see declaration of 'GenApi::IInteger::operator ='
'int64_t GenApi::IInteger::GetValue(bool,bool)' : is abstract
...
The JNI line that fails looks like this:
::GenApi::CValueRefT<GenApi::IInteger,GenApi::IInteger>* rptr = new ::GenApi::CValueRefT<GenApi::IInteger,GenApi::IInteger>();
This kind of makes sense
since IInteger
methods, like operator =,
are not defined. What is puzzling me is that this thing somehow
works in C++ code camera.MaxNumBuffer = 5.
The question is what is needed to make it work in Java wrapper?
Any hints?
Thanks,
Jarek
It might just need the purify() hint in the InfoMap. The Parser is not very smart...
Samuel
--
You received this message because you are subscribed to the Google Groups "javacpp" group.
To unsubscribe from this group and stop receiving emails from it, send an email to javacpp-proje...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
On 8/27/2015 1:54 AM, Samuel Audet wrote:
It might just need the purify() hint in the InfoMap. The Parser is not very smart...
I added:
new Info(“GenApi::IInteger”).purify()
That was still having
the same problem, so added virtualize:
new Info(“GenApi::IInteger”).purify().virtualize()
This caused generation
of wrappers for pure virtual methods in of IInteger
(before only constructors were generated) . Now the error cannot instantiate abstract class
shifted to different place, wrapper for operator =,
it is defined in C++ as:
interface GENAPI_DECL_ABSTRACT IInteger : virtual public IValue
{
virtual IInteger& operator=(int64_t Value) = 0;
…
};
To avoid issues with
instantiation in operator =
added skip:
new Info("GenApi::IInteger::operator =").skip()
A this point, there
seems to be an issue with Parser. It quits with an error Could not parse declaration at '0'
in line:
virtual IInteger& operator=(int64_t Value) = 0;
Stack trace for the error:
Caused by: org.bytedeco.javacpp.tools.ParserException: C:\Program Files\Basler\pylon 4\genicam\library\cpp\include\GenApi\IInteger.h:61: Could not parse declaration at '0'
at org.bytedeco.javacpp.tools.Parser.declarations(Parser.java:2305)
at org.bytedeco.javacpp.tools.Parser.group(Parser.java:1940)
at org.bytedeco.javacpp.tools.Parser.declarations(Parser.java:2299)
at org.bytedeco.javacpp.tools.Parser.namespace(Parser.java:2208)
at org.bytedeco.javacpp.tools.Parser.declarations(Parser.java:2298)
at org.bytedeco.javacpp.tools.Parser.parse(Parser.java:2374)
at org.bytedeco.javacpp.tools.Parser.parse(Parser.java:2469)
at org.bytedeco.javacpp.tools.Builder.parse(Builder.java:66)
at org.bytedeco.javacpp.tools.Builder.build(Builder.java:623)
at org.bytedeco.javacpp.tools.BuildMojo.execute(BuildMojo.java:269)
... 21 more
Looks that the Parser
gets confused while skipping a pure virtual method. There is no
error from Parser when new Info("GenApi::IInteger::operator =").skip()
is not used. Looks like a bug in Parser?
Jarek
On 9/6/2015 9:51 AM, Samuel Audet wrote:
Right, it'll be easier with more context. I'll be waiting. Thanks!
The initial version of
the presets for Pylon is in jpsacha/javacpp-presets
on branch wip/pylon.
The committed code build correctly (though only some things are
wrapped). Sample code using the working parts of the Pylon
wrapper is in javacv-examples
on branch wip/pylon.
I tested both on Windows 7 64.
To see the error as described earlier in this thread uncomment line 96 in GenICam2.java. You may need to comment lines 97 to 99. There couple of other errors show up to when you uncomment other include files.
Jarek
The initial version of the presets for Pylon is in jpsacha/javacpp-presets on branchwip/pylon. The committed code build correctly (though only some things are wrapped). Sample code using the working parts of the Pylon wrapper is in javacv-examples on branchwip/pylon. I tested both on Windows 7 64.To see the error as described earlier in this thread uncomment line 96 in GenICam2.java. You may need to comment lines 97 to 99. There couple of other errors show up to when you uncomment other include files.
Thanks for the
suggestion. This makes the code compile with no issues. Now the
problem is with the usage. CCamera
has a member defined in C++ as:
GenApi::IInteger &MaxNumBuffer;
In C++ when you assigned
value to MaxNumBuffer
it is simply:
camera.MaxNumBuffer = 5;
There is some behind the
scenes conversion happening where integer 5
is converted to CIntegerRef
(IInteger &)
and assigned to MaxNumBuffer.
I tries something like this:
CIntegerRef maxNumBuffer = new CIntegerRef(1)
maxNumBuffer.SetValue(5)
camera.MaxNumBuffer(maxNumBuffer)
but that result in run-time error from C++ libraries:
Feature not present (reference not valid) : AccessException thrown (file 'IInteger.h', line 129)
That line is:
virtual void SetValue(int64_t Value, bool Verify = true)
{
if(ref::m_Ptr)
return ref::m_Ptr->SetValue(Value, Verify);
else
throw ACCESS_EXCEPTION("Feature not present (reference not valid)");
}
There is some C++
“magic” happening when 5
is converted to CIntegerRef
that somehow needs to be expressed in preset. Any hints what may
be going on?
Jarek
Theoretically that would
work, but requires some adjustments in the presets. MaxNumBuffer()
returns IInteger &,
in the wrapper it returns IInteger.
In C++
In the generated wrapper
IInteger
only
provides constructors. In C++ IInteger
has methods:
interface GENAPI_DECL_ABSTRACT IInteger : virtual public IValue
{
virtual void SetValue(int64_t Value, bool Verify = true) = 0;
virtual IInteger& operator=(int64_t Value) = 0;
virtual int64_t GetValue(bool Verify = false, bool IgnoreCache = false ) = 0;
virtual int64_t operator()() = 0;
...
}
So if these methods were
wrapped we could use MaxNumBuffer().SetValue(5)
or MaxNumBuffer().put(5).
I tried adding to presets:
.put(new Info("GenApi::IInteger").purify())
that does not change
anything.
Tried virtualize(),
that leads to a series of JNI compilation errors, some related
to IInteger
operator wrapper code, the last one:
error C2259: 'GenApi::IInteger' : cannot instantiate abstract class
Kind of back to where it all stared.
By the way I tested type
of the value returned by MaxNumBuffer
in C++:
cout << "NamV " << typeid(camera.MaxNumBuffer).name() << e
ndl;
the output was:
NamV class GenApi::CIntegerRefT<struct GenApi::IInteger,struct GenApi::IInteger>
Which is the same as CIntegerRef,
which has SetValue
and put
that can be used to assign Long value.
In the wrapper MaxNumBuffer
returns IInteger.
May be this can be somehow annotated so wrapper will return CIntegerRef
rather than IInteger.
That could solve the issue. Would it be possible?
Jarek
Theoretically that would work, but requires some adjustments in the presets.
MaxNumBuffer()returnsIInteger &, in the wrapper it returnsIInteger. In C++In the generated wrapper
IIntegeronly provides constructors. In C++IIntegerhas methods:
The generated many new
methods in several classes, including messing methods in IInteger.
The sample code compiles with:
camera.MaxNumBuffer().SetValue(5)
But it crashes at
runtime on invocation of SetValue(5),
something if I use put(5).
Here is the error log:
--------------- T H R E A D ---------------
Current thread (0x00000000021cb000): JavaThread "main" [_thread_in_native, id=2016, stack(0x00000000022f0000,0x00000000023f0000)]
siginfo: ExceptionCode=0xc0000005, reading address 0xffffffffffffffff
Registers:
...
Register to memory mapping:
RAX=0x000007feef054910 is an unknown value
RBX=0x00000000021cb1f8 is an unknown value
RCX=0x000007feef07f118 is an unknown value
RDX=0x0000000000000005 is an unknown value
RSP=0x00000000023ee4c0 is pointing into the stack for thread: 0x00000000021cb000
RBP=0x00000000023ee588 is pointing into the stack for thread: 0x00000000021cb000
RSI=0x00000000023ee5b8 is pointing into the stack for thread: 0x00000000021cb000
RDI=0x0000000000000005 is an unknown value
R8 =0x0000000000000001 is an unknown value
R9 =0x000000076c5e72c8 is an oop
org.bytedeco.javacpp.GenICam2$IInteger
- klass: 'org/bytedeco/javacpp/GenICam2$IInteger'
R10=0x0000000000000004 is an unknown value
R11=0x0000000053301258 is an unknown value
R12=0x0000000000000000 is an unknown value
R13=0x000000001c1add50 is pointing into metadata
R14=0x000007feef07f118 is an unknown value
R15=0x00000000021cb000 is a thread
Stack: [0x00000000022f0000,0x00000000023f0000], sp=0x00000000023ee4c0, free space=1017k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C [jniGenICam2.dll+0x8c74]
C 0x00000000026d5e34
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j org.bytedeco.javacpp.GenICam2$IInteger.SetValue(J)V+0
Should I check something
specific?
Is there some option not to delete the generated JNI code?
Jarek
On 10/15/2015 9:34 AM, Samuel Audet wrote:
Hi Jarek,
Are you having any luck with all this these days? You're encountering a runtime error, and I don't have a Basler camera so it's hard for me to debug. If you can provide more data to analyze, please do. Maybe we can figure out something together. Thanks!
I finally have an
example that does not require a camera. It can be tested with CImageFormatConverter:
import org.bytedeco.javacpp.GenICam3.IFloat;
import org.bytedeco.javacpp.Pylon5.CImageFormatConverter;
...
CImageFormatConverter converter = new CImageFormatConverter();
IFloat gamma = converter.Gamma();
// This should execute without crashing JVM
double gammaValue = gamma.GetValue();
// Set to new value
gamma.SetValue(1.2);
In the code above
accessing the value of gamma
is crashing the JVM. It is using IFloat
that is similar to IInteger
discussed earlier. This code is also a part of a test
case in the Pylon-demo.
Note that converter itself is working fine as illustrated in this
example, just setting of some of its parameters is not
working.
Home this helps in tracking the issue.
Jarek
#pragma warning ( disable : 4251 ) // XXX needs to have dll-interface to be used by clients of class YYYWhich could cause problems for users not using the exact same version of Visual Studio:
Hi, Jarek,
Sorry for taking so much time, but I've started to look at this, and there doesn't appear to be anything special about that code, so I'd like to make sure of one thing: Are you using Visual Studio 2013?
So let me know if you still have issues with that and I'll take a closer look. Thanks!
This is still an issue. Just tested with the latest version of JavaCPP. This is the most significant issue hampering progress with Pylon wrapper right now, many camera parameters rely on this construct (IInteger, IFloat, etc).
infoMap.put(new Info("Pylon::CImageFormatConverter").base("Pointer"));
infoMap.put(new Info("Pylon::CImageFormatConverter::~CImageFormatConverter()").javaText(
"@Namespace @Name(\"static_cast<Basler_ImageFormatConverterParams::CImageFormatConverterParams_Params*>\")\n" +
" public static native CImageFormatConverterParams_Params params(CImageFormatConverter c);\n" +
"public CImageFormatConverterParams_Params params() { return params(this); }"));
And then we can get and set parameters this way:Thanks for the info. I
will try to figure out how best to use it. It may be a couple of
days.
The problem is not only with CImageFormatConverter.
It is in all the paces where IFloat,
IInteger,
etc. are used that I seen so far. That may be an issue with
GenICam that Pylon is based on. CImageFormatConverter
was only used here as an example that does not required a camera
to run. I did not have issues with the equivalent code written
in C++, only in wrappers.
Jarek
Thanks for the info. I will try to figure out how best to use it. It may be a couple of days.
The problem is not only withCImageFormatConverter. It is in all the paces whereIFloat,IInteger, etc. are used that I seen so far. That may be an issue with GenICam that Pylon is based on.CImageFormatConverterwas only used here as an example that does not required a camera to run. I did not have issues with the equivalent code written in C++, only in wrappers.
infoMap.put(new Info("Basler_ImageFormatConverterParams::CImageFormatConverterParams_Params").flatten());
Let me know if you encounter any problems with that! ThanksOn 12/25/2015 10:48 PM, Samuel Audet wrote:
I think I've come up with a better solution in this commit: https://github.com/bytedeco/javacpp/commit/cbee6ca6a7b6756b7fdfd3e86c55868c86a39534
I've added an Info.flatten flag to basically copy/paste the declarations of base classes into their subclasses. So, after adding the line below to the presets, your example code for CImageFormatConverter works as is without any additional funny syntax:
infoMap.put(new Info("Basler_ImageFormatConverterParams::CImageFormatConverterParams_Params").flatten());Let me know if you encounter any problems with that! Thanks
This is better then the
other one. Easier to declare and easier to use, no need for params
:)
In general it works.
However, it seems omits to copy the very first method
declaration to subclasses. For instance, CImageFormatConverterParams_Params
has first method called MonoConversionMethod
(l.7543)
that is not copied to CImageFormatConverter,
the first copied method is Gamma
(l.7848).
Similarly CInstantCameraParams_Params
has first method MaxNumBuffer
(l.3474)
that is not copied to CInstantCamera
(l.4671).
Thanks,
Jarek
Right, I've fixed that in the latest commit:
https://github.com/bytedeco/javacpp/commit/193fab81868560ac674a938b294afe3e8eaedb89
On 1/9/2016 12:10 AM, Samuel Audet wrote:Thanks. That fixed the issue. Seems to be working fine.
Am Montag, 11. Januar 2016 01:03:22 UTC+1 schrieb Jarek Sacha:
--
You received this message because you are subscribed to the Google Groups "javacpp" group.
To unsubscribe from this group and stop receiving emails from it, send an email to javacpp-proje...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/javacpp-project/b550b4b9-bfb1-4001-bd44-188c8bd7d320%40googlegroups.com.
The latest Pylon wrapper code I have is in this fork:It was not updated in a couple of years. I am no longer work on Pylon wrappers.Examples of using those wrappers are on this branch of javacv-examples:Jarek
On Tue, Dec 3, 2019 at 4:00 AM Crystal Black <broadwa...@gmail.com> wrote:
Hello! You have java code for Basler? could you please post your code to control the Basler cam with Java?--
четверг, 13 апреля 2017 г., 2:38:26 UTC+5 пользователь Uwe König написал:Am Montag, 11. Januar 2016 01:03:22 UTC+1 schrieb Jarek Sacha:On 1/9/2016 12:10 AM, Samuel Audet wrote:Thanks. That fixed the issue. Seems to be working fine.
Jarak,
could you please post your code to control the Basler cam with Java? We have exeactly the same task here but at the moment no expierence with Pylon, C++ or JNI.
Thank you in advance.
Uwe
You received this message because you are subscribed to the Google Groups "javacpp" group.
To unsubscribe from this group and stop receiving emails from it, send an email to javacpp...@googlegroups.com.