Jump to content
Adam

Access Violation using TVariantManager.VarToInt64

Recommended Posts

Hi,

 

Just wondering if anyone can please tell me what I'm doing wrong here. Calling VarToInt64 brings up an access violation:

 

var
 v : Variant;
 N : Int64;
 VMGR : TVariantManager;
begin
  v := 1234567890;
  N := VMGR.VarToInt64(v);
end;

Thanks & Regards

 

Adam

Share this post


Link to post

It's obsolated do not use it (as it cannot be used). Checked even in XE5 was deprecated.

 

I wonder why it is not removed from the source.

Edited by Lajos Juhász

Share this post


Link to post

Yet no mention of that in the help files. :classic_dry: Thanks for pointing that out. What's safe to use then Just n := v?

Edited by Adam

Share this post


Link to post
1 hour ago, Adam said:

What's safe to use then Just n := v?

Yes

Edited by David Heffernan
  • Thanks 1

Share this post


Link to post
16 hours ago, Adam said:

Calling VarToInt64 brings up an access violation:

You are instantiating a TVariantManager instance without populating it, so it has unassigned function pointers at the time you are calling VarToInt64().  You would need to call GetVariantManager() first to initialize the record before you can use it, eg:

var
  v : Variant;
  N : Int64;
  VMGR : TVariantManager;
begin
  v := 1234567890;
  if IsVariantManagerSet then
  begin
    GetVariantManager(VMGR);
    N := VMGR.VarToInt64(v);
  end;
end;

However, TVariantManager has been deprecated for a very long time (since sometime between D7..D2006, so approx 20 years!), so wherever did you get the idea that you need to use it in the first place? Since at least D2006 (maybe earlier), GetVariantManager() just fills the record with nil pointers, and IsVariantManagerSet() always returns False.

 

In modern coding, simply assign the Variant directly to the Int64 variable and let the compiler handle the conversion for you, eg:

var
  v : Variant;
  N : Int64;
begin
  v := 1234567890;
  N := v; // compiler generates: N := System.Variants._VarToInt64(v);
end;

 

Edited by Remy Lebeau
  • Thanks 1

Share this post


Link to post
38 minutes ago, Remy Lebeau said:

You would need to call GetVariantManager() first to initialize the record before you can use it, eg:

You should check the implementation for that procedure:

 

{ ----------------------------------------------------- }
{       Variant manager support   (obsolete)            }
{ ----------------------------------------------------- }

procedure GetVariantManager(var VarMgr: TVariantManager);
begin
  FillChar(VarMgr, sizeof(VarMgr), 0);
end;
 

This will not fill the record properly.

Share this post


Link to post

Thanks all for your replies.

 

4 hours ago, Remy Lebeau said:

 

However, TVariantManager has been deprecated for a very long time (since sometime between D7..D2006, so approx 20 years!), so wherever did you get the idea that you need to use it in the first place?


 

I have no idea. I've been with Delphi since v1. I guess every now and then the brain does something funny and brings back something that I did years ago as though it's still applicable. :classic_laugh:

 

I appreciate the clarification. Thanks all!

Share this post


Link to post
7 hours ago, Lajos Juhász said:

You should check the implementation for that procedure:

I did, actually.

Quote

This will not fill the record properly.

I stated as much in my earlier reply:

Quote

Since at least D2006 (maybe earlier), GetVariantManager() just fills the record with nil pointers, and IsVariantManagerSet() always returns False.

 

Edited by Remy Lebeau

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×