PDA

View Full Version : AXIS camera SDK with QVariant problem : cannot access private member declared inclass



szysagittarius
9th May 2014, 19:36
Hey, guys,

I am new here, I am playing with AXIS network camera using its SDK based on QT. I want to use its GetCurrentImage function to get the Image.

Below is the syntax of GetCurrentImage from AXIS SDK.

GetCurrentImage
Syntax
HRESULT GetCurrentImage(int theFormat, [C++]
VARIANT* theBuffer,
LONG* theBufferSize
);
Parameters
theFormat
Identifier specifiying the format of the image data. Values available are: 0 = JPEG, 1 = BMP (defined in the AMC_IMAGE_FORMAT enum in the type library).

theBuffer
The buffer where the image data is returned.

theBufferSize
Size of the image data buffer returned.

It looks like assigning the “theBuffer” field passing by reference, like the format below



var* var;

getCurrentImage(var){ // object-> dynamicallcall(“getCurrentImage(var)”)

var = … // which can not be seen by us, because I am using dynamiccall to call the method in AXIS SDK

}




So I choose QVariant to do that

(1) In the .h file under public declaration,
QVariant* MediaBuffer;
long* MediaBufferSize;

(2) in the .cpp file
I first tried


axWidget->dynamicCall("GetCurrentImage(int, QVariant*, long*)",0,MediaBuffer, MediaBufferSize);


then I got the error report twice:

error: C2248: 'QVariant::QVariant' : cannot access private member declared in class 'QVariant'
e:\qt\4.8.5\src\corelib\kernel\qvariant.h:429: see declaration of 'QVariant::QVariant'
e:\qt\4.8.5\src\corelib\kernel\qvariant.h:93: see declaration of 'QVariant'
error: C2248: 'QVariant::QVariant' : cannot access private member declared in class 'QVariant'
e:\qt\4.8.5\src\corelib\kernel\qvariant.h:429: see declaration of 'QVariant::QVariant'
e:\qt\4.8.5\src\corelib\kernel\qvariant.h:93: see declaration of 'QVariant'

in the second time, I tried



QList<QVariant> varList;
varList << 0 << MediaBuffer << MediaBufferSize; // error report place
axWidget->dynamicCall("GetCurrentImage(int, QVariant*, long*)",varList);
axWidget->dynamicCall("GetCurrentImage(QList<QVariant>)",varList); // the same error report



I got the same error report

Looking deeper at the qvariant.h,
In line 429 it is



private:
// force compile error, prevent QVariant(bool) to be called
inline QVariant(void *) { Q_ASSERT(false); } // line 429



in line 93
it is


class Q_CORE_EXPORT QVariant


which I do not list all stuff here.

It seems the problem of the usage of QVariant up to now, but I do not know how can I fix it.

Could you guys give me some suggestions?


My environment is
Qt 4.8.5
Qtcreator 3.1.0
Win 8
AXIS Media Control API 6.30


Many thanks,
szysagittarius

anda_skoa
9th May 2014, 20:17
Below is the syntax of GetCurrentImage from AXIS SDK.

GetCurrentImage
Syntax
HRESULT GetCurrentImage(int theFormat, [C++]
VARIANT* theBuffer,
LONG* theBufferSize
);
Parameters

Well, this is definitely not a Qt API.

HRESULT strongly indicates a Windows API.

Cheers,
_

szysagittarius
10th May 2014, 02:39
Yes, my friend
I use axWidget->dynamicCall("GetCurrentImage(int, QVariant*, long*)",0,MediaBuffer, MediaBufferSize);
to call windows API in my first try

but I found the compiler report error even before running to this line, I am suspecting that it has something wrong with usage of QVariant using QList
But I do not know how to fix it


I just filed my code and share it on github in the link below
https://github.com/szysagittarius/AxisGetCurrentImageUsingQt/tree/master

except the getCurrentImage function can not work properly, other functions works fine.

you can play with this code after installing the AXIS Media Control sdk, which only need few second to install them
below is the address of AXIS Media Control sdk,

http://www.axis.com/techsup/cam_servers/dev/activex.htm


the function document is under the doc in the installing directory (..\AXIS Media Control SDK\doc)

If you have any suggestion after playing with this code, we can discuss here :)






Well, this is definitely not a Qt API.

HRESULT strongly indicates a Windows API.

Cheers,
_

anda_skoa
10th May 2014, 11:00
Yes, my friend
I use axWidget->dynamicCall("GetCurrentImage(int, QVariant*, long*)",0,MediaBuffer, MediaBufferSize);
to call windows API in my first try

It is a Windows (ActiveX) API, it obviously doesn't know anything about Qt types such as QVariant.

If you want to use this Windows API you'll have to use the respective data types.

Earlier you wrote:


I am playing with AXIS network camera using its SDK based on QT

wouldn't it be easier to use the Qt API of the SDK instead?

Cheers,
_

szysagittarius
10th May 2014, 16:09
hummm! your words really make sense, I will try to find solution by using pure C++ in Qt when using windows API

as to Qt API, the AXIS camera product develop its own sdk, we can only get video source by using their sdk,which is windows API,
I tried to use Qt API before, like Qnetworkaccessmanager, but failed to get video source, I guess it is the way they protect they product,i.e. only their own SDK can access their network camera.

anda_skoa
10th May 2014, 17:18
How did you arrive at the conclusion that their SDK is based on Qt when there is on Qt API to use?

Or wasn't QT a typo and you really meant to write QT as in QuickTime? In which case I am sorry for the misunderstanding.

Cheers,
_

szysagittarius
11th May 2014, 18:08
QT is a typo, I am sorry for making this misunderstanding.

AXIS camera SDK can be well supported by .NET framework, and their products is demonstrated by using C# and VC++,

Here I am trying to use ActiveQt framework to call method of that COM to set the value of two local variables (1) QVariants* MediaBuffer; (2) LONG* MediaBufferSize;

By calling

GetCurrentImage
Syntax
HRESULT GetCurrentImage(int theFormat, [C++] VARIANT* theBuffer, LONG* theBufferSize);


I double checked the the Supported COM datatypes in QAxBase Class Reference, that I want say that previously your reminding that windows API do not know Qt type, this worry may not exist any more (this is just my understanding)
below is the link:
http://qt-project.org/doc/qt-4.8/qaxbase.html#dynamicCall

At the first time, I tried to use dynamiccall ( const char * function, QList<QVariant> & vars ) to let this COM method to return and assign those two values
but I double checked the document, It seems that this function only can set value to the COM function, it will report


QAxBase: Error calling IDispatch member GetCurrentImage: Type mismatch in parameter 2

if I want to get the returned value by this method calling

So now I am trying to use methods like these


QString text = object.property("text").toString();
object.setProperty("font", QFont("Times New Roman", 12));


to try to assign the values to my two local variables

but the hard point is this GetCurrentImage method return two parameters at the same time, then I have no idea how to assign my two local variables now based on the example provided by the Qt class reference

Do you have any suggestions on that situation?

Best regards

anda_skoa
11th May 2014, 18:34
Well, since that has nothing to do with Qt on the call it self, pass the same data structures that the C++ examples do.
After all Qt is just a C++ library as well, if something works in a C++ program it should work in a Qt program.

Cheers,
_

szysagittarius
13th May 2014, 03:22
I want to correct my previous remarks and update my knowledge of dynamicCall function


At the first time, I tried to use dynamiccall ( const char * function, QList<QVariant> & vars ) to let this COM method to return and assign those two values, but I double checked the document, It seems that this function only can set value to the COM function, it will report
QAxBase: Error calling IDispatch member GetCurrentImage: Type mismatch in parameter 2
if I want to get the returned value by this method calling


afterwards, I use getDocument to get the AXIS document from AXIS COM component, which describes the exact way how to call every function of AXIS media control using Qt, and it says it did should use dynamicCall to assgin MediaBuffer and MediabufferSize these two local variables.



void GetCurrentImage (int theFormat, QVariant& theBuffer, int& theBufferSize) [slot]
get the current image
Connect a signal to this slot:
QObject::connect(sender, SIGNAL(someSignal(int, QVariant&, int&)), object, SLOT(GetCurrentImage(int, QVariant&, int&)));

Or call the function directly:
QVariantList params = ...
object->dynamicCall("GetCurrentImage(int, QVariant&, int&)", params);



So the code can be written like this


QVariant MediaBuffer;
long MediaBufferSize;
QList<QVariant> varList;
varList << 0 << MediaBuffer << MediaBufferSize;

axWidget->dynamicCall("GetCurrentImage(int, QVariant&, long&)",varList);

this can solve the problem of error report"can not access to the private member in class QVariant", because QVariant can not accpet address type.

However, even I followed what the document says on how to use dynamicCall to call this GetCurrentImage function, it will still report Bad parameter count or Exception thrown by server, and can not have these two local variables assigned.

example 1:
if I use


axWidget->dynamicCall("GetCurrentImage(int, QVariant&, int&)",0,MediaBuffer,MediaBufferSize);


it will report


/QAxBase: Error calling IDispatch member GetCurrentImage: Bad parameter count



example 2

if I use


QList<QVariant> varList;
varList << 0 << MediaBuffer << MediaBufferSize;
axWidget->dynamicCall("GetCurrentImage(int, QVariant&, long&)",varList);


it will report


IDispatch member GetCurrentImage: Exception thrown by server
Code : 16389
Source :
Description:
Help :
Connect to the exception(int,QString,QString,QString) signal to catch this exception


It seems that the second example's error report cover the first one, since these two local variables still not get assigned yet, my guess is the parameter type still mismatched.

What do you think of this bizarre outcome, my friend :)

I updated my problem code and uploaded it on github, if you have interest, you can play with it.
https://github.com/szysagittarius/AxisGetCurrentImageUsingQt

Best Regards

anda_skoa
13th May 2014, 14:02
No Windows here so no ActixeX either.

Maybe you can find out what error "16389" means.

This variant of the dynamicCall() is the only one that will work for you since it has the arguments as a reference and you get output through arguments.

Another option might be to use the platform specific C++ code and convert the retrieved data to Qt types afterwards.

Cheers,
_