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?
"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
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
>
"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
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
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