I want to add more options to my ARX/ATL project, by adding some new functions that will be exported via Platform Invocation Services (PInvoke).
Note: First time I use extern "C" __declspec(dllexport)
For example:
ARX function:
extern "C" __declspec(dllexport)
void GbPeIntPoly(AcGePoint3d ipt,const TCHAR *LayerName,double dtol,short poltip,double areamin,short dirpolhor,LONG *objid)
{
AcDbLayerTable *LayerTable=NULL;
acdbHostApplicationServices()->workingDatabase()->getSymbolTable(LayerTable,AcDb::kForRead);
if(!LayerTable->has(LayerName))
LayerName=_T("0");
LayerTable->close();
ads_name sspol;
intergbpoly(ipt,LayerName,dtol,poltip,areamin,dirpolhor,sspol);
long length=0;
if ((acedSSLength(sspol,&length) != RTNORM) || (length==0))
{
acedSSFree(sspol);
return;
}
AcDbObjectId objId;
ads_name ename;
acedSSName(sspol,0,ename);
if (acdbGetObjectId(objId,ename) != Acad::eOk) return;
acedSSFree(sspol);
*objid=objId.asOldId();
}
Pinvoke call: Note on this was no problem, at all.
[DllImport("GbPolyEngine17.arx", CharSet = CharSet.Auto, EntryPoint = "GbPeIntPoly")]
public static extern void GbPeIntPoly(Point3d point, string layer, double tol, short poltype, double minarea, short poldir, out ObjectId id);
C# function: Note this function works as expected.
[CommandMethod("InPoly")]
static public void GbPolyInPoly()
{
Document doc = AcadApp.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
Database db = doc.Database;
PromptPointResult ptRes = ed.GetPoint("\nPick internal point: ");
if (ptRes.Status != PromptStatus.OK) return;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
ObjectId id = new ObjectId();
Point3d point = new Point3d();
point = ptRes.Value;
string polLayer = "TEST"; // Polyline layer - default="0"
double polTol = 0.001; // Tolerance to find intersections
short polType = 0; // 0=LWPOLYLINE, 1=POLYLINE
double polMin = 20.0; // Minimum area for polyline generation
short polDir = 1; // 0=CLOCKWISE 1=COUNTER-CLOCKWISE
GbPeIntPoly(point, polLayer, polTol, polType, polMin, polDir, out id);
if (id.IsValid)
{
Polyline poly = tr.GetObject(id, OpenMode.ForRead, false) as Polyline;
if (poly != null)
{
ed.WriteMessage("\nThe entity is one [" + poly.GetType().Name + "]");
ed.WriteMessage("\nObjectId is [{0}]", id.ToString());
// the generated polyline is now here open for read.
}
}
else if (!id.IsValid && id.IsNull)//test
ed.WriteMessage("\nObjectId is not valid and null [{0}]", id.ToString());
tr.Commit();
}
} //end of InPoly
And here is another ARX function:
extern "C" __declspec(dllexport)
void GbPeSSPoly(AcDbObjectIdArray ids,const TCHAR *LayerName,const TCHAR *LayerNameOut,double dtol,short poltip,double areamin,short inpol,short outpol,short dirpolhor,AcDbObjectIdArray *objids)
{
// layers exists?
AcDbLayerTable *LayerTable=NULL;
acdbHostApplicationServices()->workingDatabase()->getSymbolTable(LayerTable,AcDb::kForRead);
if(!LayerTable->has(LayerName))
LayerName=_T("0"); // default
if(!LayerTable->has(LayerNameOut))
LayerNameOut=_T("0"); // default
LayerTable->close();
ads_name sspol;
if (!ids.isEmpty())
gbpoly(ids,LayerName,LayerNameOut,dtol,poltip,areamin,inpol,outpol,dirpolhor,sspol);
// now verify if the selection set has some generated polylines
long len=0;
if ((acedSSLength(sspol,&len) != RTNORM) || (len==0))
{
acedSSFree(sspol);
return;
}
// fill the output array of object ids
for (int i=0; i<len; i++)
{
AcDbObjectId objId;
ads_name ename;
acedSSName(sspol,i,ename);
if (acdbGetObjectId(objId,ename) != Acad::eOk) return;
objids->append(objId);
}
acedSSFree(sspol);
}
Here is my question, where I can find a table or something like the attached image or the equivalent of AcDbObjectIdArray in CLR Type?I had tried something like:
[DllImport("GbPolyEngine17.arx", CharSet = CharSet.Auto, EntryPoint = "GbPeSSPoly")]
public static extern void GbPeSSPoly(ObjectIdCollection ids, string layerInternal, string layerExternal, double tol, short poltype, double minarea, short inpol, short outpol, short poldir, out ObjectIdCollection oids);
//public static extern void GbPeSSPoly(ObjectId[] ids, string layerInternal, string layerExternal, double tol, short poltype, double minarea, short inpol, short outpol, short poldir, out ObjectId[] oids);
[CommandMethod("SsPoly")]
static public void GbPolySsPoly()
{
Document doc = AcadApp.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
Database db = doc.Database;
PromptSelectionOptions prOpts = new PromptSelectionOptions();
prOpts.MessageForAdding = "\nSelect curve objects: ";
TypedValue[] filter = new TypedValue[1];
Object obj = "LINE,ARC,LWPOLYLINE,POLYLINE,CIRCLE";
filter[0] = new TypedValue(0, obj);
SelectionFilter ssFilter = new SelectionFilter(filter);
PromptSelectionResult res = ed.GetSelection(prOpts, ssFilter);
if (res.Status != PromptStatus.OK) return;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
string layerInternal = "TESTINT";
string layerExternal = "TESTEXT";
double tol = 0.5;
short poltype = 1;
double minarea = 20.0;
short inpol = 1;
short outpol = 1;
short poldir = 1;
ObjectIdCollection ids = new ObjectIdCollection();
ObjectIdCollection oids = new ObjectIdCollection();
foreach (ObjectId id in res.Value.GetObjectIds())
ids.Add(id);
//ObjectId[] oids = new ObjectId[res.Value.Count];
try
{
//GbPeSSPoly(res.Value.GetObjectIds(), layerInternal, layerExternal, tol, poltype, minarea, inpol, outpol, poldir, out oids);
GbPeSSPoly(ids, layerInternal, layerExternal, tol, poltype, minarea, inpol, outpol, poldir, out oids);
}
catch (System.Exception ex)
{
ed.WriteMessage("Error: " + ex.Message);
}
tr.Commit();
}
}
Show this error:
Select curve objects:
Error: This type has a ComVisible(false) parent in its hierarchy, therefore
QueryInterface calls for IDispatch or class interfaces are disallowed.
Now, I have seen the free pinvoke add-in for VS from pinvoke.net, but have not downloaded, might that work?.... I had use Depends.exe with other dll's and return data types that helps, but not for this arx (that is an ATL COM)
Thanks!
Luis.