Board index » delphi » Using variant arrays in ole automation

Using variant arrays in ole automation

Can someone give examples on how to communicate (from Delphi) with an
automation server
that requires arguments that are variant arrays. Specifically we have tried
to do this against
AutoCad r14. It was simple from Visual Basic, but never worked from Delphi.

Also I would like examples on how to create a Delphi automation server
taking variant arrays as arguments.

/Bj?rn

 

Re:Using variant arrays in ole automation


I have the same problem with Delphi 2 and AutoCAD R14. When I try this:

  v1 := VarArrayCreate ([0, 2], varDouble);
  v2 := VarArrayCreate ([0, 2], varDouble);

  v1 [0] := 0;
  v1 [1] := 0;
  v1 [2] := 0;
  v2 [0] := 100;
  v2 [1] := 100;
  v2 [2] := 0;

  try
    AcadApp := GetActiveOleObject (CLSID);  { CLSID =
'AutoCAD.Application' }
  except
    try;
    AcadApp := CreateOleObject (CLSID);
    except
      Result := 200;
      exit;
      end;
    end;

  try
    AcadDoc := AcadApp.ActiveDocument;
  except
    Result := 201;
    exit;
    end;

  try
    MoSpace := AcadDoc.ModelSpace;
  except
    Result := 202;
    exit
    end;

  try
    MoSpace.AddLine (v1, v2);
  except
    Result := 203;
    exit;
    end;

In line "MoSpace.AddLine (v1, v2);" I get a runtime error. Who can help?

To create automation servers in Delphi, I have a good description in
German. Please let me know, if it will help you.

Roland Brandegger

Re:Using variant arrays in ole automation


Autodesk is about to release a revision of AutoCAD which
eliminates the problem with Variant arrays.  You need to
use Delphi 3.01 for controlling AutoCAD.

Here's a copy of a message I posted on it some time back,
but beware that things will change when the AutoCAD update is
released, but the example code shown will continue to work.

========================================================

If you're using Late binding, then you must use the
VarArrayRef() function to pass a variant array when
AutoCAD requires an array of 3 doubles (a 3D coordinate).

Here's an example using Late binding, which draws a
circle:

var
  Acad, Circle, vPoint, Mspace : OleVariant;
begin
  vPoint := VarArrayCreate([0,2], VT_R8);
  vPoint[0] := 2.0;
  vPoint[1] := 4.0;
  vPoint[2] := 0.0;

  Acad := GetActiveOleObject('AutoCAD.Application.14');

  Mspace := Acad.ActiveDocument.Modelspace;

 // call the AddCircle() method passing it the
 // coordinate in vPoint:

 Circle := Mspace.AddCircle(VarArrayRef(vPoint), 10.0);
 Circle.Update;

end;

With Early binding its a bit more complicated. Delphi 3.0 has
a bug that incorrectly declares SafeArray's as OleVariants
in the imported type library (and generates a warning for
each, but even the warning is incorrect - these parameters
must be declared as const PSafearray (a constant pointer
to a TSafeArray). This is fixed in Delphi 3.01, but in the
update to AutoCAD, it will not matter, since all points are
declared as variants rather than Safearray(double).

So, for the AddCircle() method used in the above example,
this would be the correct declaration that must appear
in AutoCAD_TLB.pas:

function AddCircle(const center: PSafeArray; radius: Double): IDispatch;
safecall;

Assuming you correct the declaration to read like the
above, to use Early binding you must pass the safearray
pointer. You can use this helper function to convert a
variant array to a PSafeArray:

Function SafeArrayRef(V : OleVariant): PSafeArray;
begin
  Result := PSafeArray(TVarData(V).VArray);
end;

This example does the same as the previous one, only
it uses early binding:

var
  Acad, vPoint: OleVariant;
  Mspace : IAcadModelSpace;
  Circle : IAcadCircle;
begin
  vPoint := VarArrayCreate([0,2], VT_R8);
  vPoint[0] := 2.0;
  vPoint[1] := 4.0;
  vPoint[2] := 0.0;

  Acad := GetActiveOleObject('AutoCAD.Application.14');

  Mspace := IDispatch(Acad.ActiveDocument.ModelSpace) as IAcadModelspace;

  Circle := IDispatch(Mspace.AddCircle(SafeArrayRef(vPoint), 10.0)) as
IAcadCircle;

  Circle.Update;

end;

Bjorn Lindell <b...@carasoft.se> wrote in article <65m12p$1cj4@forums>...

Quote
> Can someone give examples on how to communicate (from Delphi) with an
> automation server
> that requires arguments that are variant arrays. Specifically we have
tried
> to do this against
> AutoCad r14. It was simple from Visual Basic, but never worked from
Delphi.

> Also I would like examples on how to create a Delphi automation server
> taking variant arrays as arguments.

> /Bj?rn

Re:Using variant arrays in ole automation


See my response to the original post. You'll find that there's
problems with using Delphi 2 for automation control with AutoCAD.

You should use Delphi 3.01.

Roland Brandegger <roland.brandeg...@ubeco.com> wrote in article
<347ECFCD.3...@ubeco.com>...

Quote
> I have the same problem with Delphi 2 and AutoCAD R14..........

Other Threads