Mega Search
23.2 Million


Sign Up

Make a donation  
How to use variant type  
News Group: borland.public.delphi.nativeapi.win32

Hi,
I have a trouble in using variant types.
I'm developing a software which communicates with canon digital camera by 
its SDK.
There is a function that get data from camera. defenition of function as 
below:

cdCAPI CDGetDevicePropertyData( cdHSource hSource, cdDevicePropertyID 
DevPropID, cdUInt32* pBufSize, cdVoid * pBuf, cdUInt32 Option );
(clear this defined as C)
cdCAPI, cdHSource, cdDevicePropertyID, cdUInt32 are as integer type and 
cdVoid as Variant.
DevPropID is input and pBuf  is output, by DevPropID the type of pBuf may 
change. It may be Integer, String or Boolean.

I define pBuf as below:
  var pBuf: Variant;
after calling function (without error) finishing the procedure I got an 
error message that says variant type is invalid and any use of the pBuf 
raise an error exception.

How can use variant variables?



Vote for best question.
Score: 0  # Vote:  0
Date Posted: 6-Jan-2008, at 9:51 AM EST
From: Shahram Shafieha
 
Re: How to use variant type  
News Group: borland.public.delphi.nativeapi.win32
Thank you, I'll test and inform you. 



Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 9-Jan-2008, at 6:18 PM EST
From: Shahram Shafieha
 
Re: How to use variant type  
News Group: borland.public.delphi.nativeapi.win32
"Shahram Shafieha"  wrote in message 
news:478398dc@newsgroups.borland.com...

> Here is C example code:

Here are the Delphi translations:

    type
        cdChar = AnsiChar;
        cdUInt32 = LongWord;
        cdReleaseControlCap = cdUInt32;

    var
        ModelName: array[0..31] of cdChar;

    // you did not show what cdCAPI is declared as, so
    // the calling convention on this is just a guess...
    function CDGetDevicePropertyData(hSource: cdHSource; DevPropID: 
cdDevicePropertyID; var pBufSize: cdUInt32; pBuf: Pointer; Option: 
cdUInt32): cdErr; stdcall;

    var
        m_RelControlCap: cdReleaseControlCap;
        bufsize: cdUInt32;
    begin
        bufsize := SizeOf(m_RelControlCap);
        err := CDGetDevicePropertyData(m_hSource, 
cdDEVICE_PROP_RELEASE_CONTROL_CAP, bufsize, @m_RelControlCap, 0);
        ...
        bufsize := SizeOf(ModelName);
        FillChar(ModelName[0], bufsize, 0);
        err := CDGetDevicePropertyData(m_hSource, cdDEVICE_PROP_MODEL_NAME, 
bufsize, ModelName, 0);
        ...
    end;

Alternatively:

    function CDGetDevicePropertyData(hSource: cdHSource; DevPropID: 
cdDevicePropertyID; var pBufSize: cdUInt32; var pBuf; Option: cdUInt32): 
cdErr; stdcall;

    var
        m_RelControlCap: cdReleaseControlCap;
        bufsize: cdUInt32;
    begin
        bufsize := SizeOf(m_RelControlCap);
        err := CDGetDevicePropertyData(m_hSource, 
cdDEVICE_PROP_RELEASE_CONTROL_CAP, bufsize, m_RelControlCap, 0);
        ...
        bufsize := SizeOf(ModelName);
        FillChar(ModelName[0], bufsize, 0);
        err := CDGetDevicePropertyData(m_hSource, cdDEVICE_PROP_MODEL_NAME, 
bufsize, ModelName[0], 0);
        ...
    end;


> Here is what i have done:
> type
>  cdVoid = pointer;

That is not what I told you to do.

>  pDevPropStruct: ^cdDevicePropertyStruct;

>  pDevPropStruct^.DevPropID := 1; //return an integer
>  pDevPropStruct^.DevPropID := 2; //return a string
>  pDevPropStruct^.DataSize := 32;

You are declaring a pointer variable, but you are not allocating any memory 
for it.  When you access the DevPropID and DataSize members, are you 
accessing random memory.  The same thing applies to you use of the pBuf 
variable.  You are declaring another pointer variable that does not actually 
point to anything, so the function can't use it correctly.


Gambit 



Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 8-Jan-2008, at 10:39 AM EST
From: Remy Lebeau \(TeamB\)
 
Re: How to use variant type  
News Group: borland.public.delphi.nativeapi.win32
Thanks for your reply.


Here is C example code:

typedef void cdVoid;
typedef          char  cdChar;
typedef unsigned long cdUInt32;
typedef cdUInt32 cdReleaseControlCap;
cdChar  ModelName[32];

cdCAPI CDGetDevicePropertyData(
 cdHSource  hSource,
 cdDevicePropertyID  DevPropID,
 cdUInt32*   pBufSize,
 cdVoid*   pBuf,
 cdUInt32   Option
);

cdReleaseControlCap m_RelControlCap;
 bufsize = sizeof(m_RelControlCap);
 err = CDGetDevicePropertyData(m_hSource, cdDEVICE_PROP_RELEASE_CONTROL_CAP, 
&bufsize, &m_RelControlCap, 0);

m_RelControlCap return an integer.

and in another part of example:
 bufsize = sizeof(ModelName);
 memset(ModelName, 0, bufsize);
 err = CDGetDevicePropertyData(m_hSource, cdDEVICE_PROP_MODEL_NAME, 
&bufsize, ModelName, 0);

ModelName is string.

I have done some changes in my code, one problem solved and another got 
rise!
Todays ago when I asked the problem, I don't know how t get the result. but 
by these change now I can get the result and show it.
Here is what i have done:
type
  cdVoid = pointer;
var
  Err: cdErr;
  pDevPropStruct: ^cdDevicePropertyStruct;
  pBuf: cdVoid;
begin
  pDevPropStruct^.DevPropID := 1; //return an integer
  pDevPropStruct^.DevPropID := 2; //return a string
  pDevPropStruct^.DataSize := 32;

  Err := CDGetDevicePropertyData(phSource, pDevPropStruct^.DevPropID, 
pDevPropStruct^.DataSize, pBuf, 0);
  CDErrorChecking(Err);

  MessageBox(Application.Handle, PChar(@pBuf), nil, 0);  //Shows integer
  MessageBox(Application.Handle, PChar(IntToStr(Integer(@pBuf))), nil, 0); 
//Shows string
end;

but after finishing procedure an access violation exception rises, and this 
error only occurs when pBuf point to a string.


"Remy Lebeau (TeamB)"  wrote in message 
news:4782758b$1@newsgroups.borland.com...
>
> "Shahram Shafieha"  wrote in message 
> news:4781d3eb@newsgroups.borland.com...
>
>> In the source code cdVoid defined as void, my mean in
>> correponding header file:
>>
>> #define cdVoid void;
>>
>> and in equvalent delphi it is defined:
>> type cdVoid = variant;
>
> That is a wrong translation.  A void is not a Variant.  Just get rid of 
> cdVoid altogether in your Delphi code and change the pBuf parameter to a 
> Pointer.  That is what it actually is in the C/C++ code anyway:
>
>    function CDGetDevicePropertyData(hSource: cdHSource; DevPropID: 
> cdDevicePropertyID; var pBufSize: cdUInt32, pBuf: Pointer; Option: 
> cdUInt32): cdCAPI;
>
>
> Gambit
> 



Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 8-Jan-2008, at 7:06 PM EST
From: Shahram Shafieha
 
Re: How to use variant type  
News Group: borland.public.delphi.nativeapi.win32
"Shahram Shafieha"  wrote in message 
news:4781d3eb@newsgroups.borland.com...

> In the source code cdVoid defined as void, my mean in
> correponding header file:
>
> #define cdVoid void;
>
> and in equvalent delphi it is defined:
> type cdVoid = variant;

That is a wrong translation.  A void is not a Variant.  Just get rid of 
cdVoid altogether in your Delphi code and change the pBuf parameter to a 
Pointer.  That is what it actually is in the C/C++ code anyway:

    function CDGetDevicePropertyData(hSource: cdHSource; DevPropID: 
cdDevicePropertyID; var pBufSize: cdUInt32, pBuf: Pointer; Option: 
cdUInt32): cdCAPI;


Gambit 



Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 7-Jan-2008, at 10:53 AM EST
From: Remy Lebeau \(TeamB\)
 
Re: How to use variant type  
News Group: borland.public.delphi.nativeapi.win32
In the source code cdVoid defined as void, my mean in correponding header 
file:
#define cdVoid void;

and in equvalent delphi it is defined:
type cdVoid = variant;

I must say I do not create delphi file.

in the C example one time an integer return from calling function and 
another time a string.
When the function wants return integer I don't get any error message but 
when the function return some pointer I get an error (Invalid variant type).

>What does TVarData(pBuf).VType give you after the function returns?
It depends on DVPropID value, for example if DVPropID = 1, 
TVarData(pBuf).VType will be Integer,
if DVPropID = 2, TVarData(pBuf).VType will be ByRef + Array + $0143, and so 
on.
I do something else, TVarData(pBuf).RawData is an array of LongInt, this 
array contains "a part" of data that I need.
TVarData(pBuf).VString or TVarData(pBuf).VPointer or TVarData(pBuf).VArray 
return same pointer, I assigned this pointer to PChar or Pointer type 
variable, but get an access violation error message! What is wrong?

"Peter Below (TeamB)"  wrote in message 
news:xn0fkv2zs24lhp003@newsgroups.borland.com...
> Shahram Shafieha wrote:
>
>> Hi,
>> I have a trouble in using variant types.
>> I'm developing a software which communicates with canon digital
>> camera by its SDK.  There is a function that get data from camera.
>> defenition of function as below:
>>
>> cdCAPI CDGetDevicePropertyData( cdHSource hSource, cdDevicePropertyID
>> DevPropID, cdUInt32* pBufSize, cdVoid * pBuf, cdUInt32 Option );
>> (clear this defined as C) cdCAPI, cdHSource, cdDevicePropertyID,
>> cdUInt32 are as integer type and cdVoid as Variant.  DevPropID is
>> input and pBuf  is output, by DevPropID the type of pBuf may change.
>> It may be Integer, String or Boolean.
>>
>> I define pBuf as below:
>>  var pBuf: Variant;
>> after calling function (without error) finishing the procedure I got
>> an error message that says variant type is invalid and any use of the
>> pBuf raise an error exception.
>>
>> How can use variant variables?
>
> It is fairly rare for a C DLL function to use variants (API VARIANT
> record type). If it really does (show the declaration of the cdVoid
> type in the C header) the function may use a variant type code that is
> not directly supported by Delphi. What does TVarData(pBuf).VType give
> you after the function returns? If it is a non-supported type code you
> have to access the data directly via a TVarData cast and also set the
> VType to something like varEmpty before the variant variable used falls
> out of scope, so the automatic cleanup done by the compiler does not
> cause an error.
>
> -- 
> Peter Below (TeamB)
> Don't be a vampire (http://slash7.com/pages/vampires),
> use the newsgroup archives :
> http://www.tamaracka.com/search.htm
> http://groups.google.com 



Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 7-Jan-2008, at 10:54 AM EST
From: Shahram Shafieha
 
Re: How to use variant type  
News Group: borland.public.delphi.nativeapi.win32
Shahram Shafieha wrote:

> Hi,
> I have a trouble in using variant types.
> I'm developing a software which communicates with canon digital
> camera by its SDK.  There is a function that get data from camera.
> defenition of function as below:
> 
> cdCAPI CDGetDevicePropertyData( cdHSource hSource, cdDevicePropertyID
> DevPropID, cdUInt32* pBufSize, cdVoid * pBuf, cdUInt32 Option );
> (clear this defined as C) cdCAPI, cdHSource, cdDevicePropertyID,
> cdUInt32 are as integer type and cdVoid as Variant.  DevPropID is
> input and pBuf  is output, by DevPropID the type of pBuf may change.
> It may be Integer, String or Boolean.
> 
> I define pBuf as below:
>  var pBuf: Variant;
> after calling function (without error) finishing the procedure I got
> an error message that says variant type is invalid and any use of the
> pBuf raise an error exception.
> 
> How can use variant variables?

It is fairly rare for a C DLL function to use variants (API VARIANT
record type). If it really does (show the declaration of the cdVoid
type in the C header) the function may use a variant type code that is
not directly supported by Delphi. What does TVarData(pBuf).VType give
you after the function returns? If it is a non-supported type code you
have to access the data directly via a TVarData cast and also set the
VType to something like varEmpty before the variant variable used falls
out of scope, so the automatic cleanup done by the compiler does not
cause an error.

-- 
Peter Below (TeamB)  
Don't be a vampire (http://slash7.com/pages/vampires), 
use the newsgroup archives :
http://www.tamaracka.com/search.htm
http://groups.google.com

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 6-Jan-2008, at 3:05 AM EST
From: Peter Below (TeamB)