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