Author Topic: Mixed/Managed C++ dll's, passing objects.  (Read 14559 times)

0 Members and 1 Guest are viewing this topic.

MickD

  • King Gator
  • Posts: 3619
  • (x-in)->[process]->(y-out) ... simples!
Re: Mixed/Managed C++ dll's, passing objects.
« Reply #15 on: September 14, 2009, 07:35:23 PM »
Thanks Daniel, I was just looking into that, all this managed lingo is a bit cryptic at times :)
"Short cuts make long delays,' argued Pippin.”
J.R.R. Tolkien

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8659
  • AKA Daniel
Re: Mixed/Managed C++ dll's, passing objects.
« Reply #16 on: September 14, 2009, 09:15:41 PM »
Anytime, I had not posted a ref class wrapper yet, but I think those are much easier.

the biggest issue is memory management, I suppose that's why Autodesk derived most all their wrappers from  DisposableWrapper (and you can too).

As far as performance goes, I recommend putting all your native code in a .lib library,  then make your managed wrappers.

MickD

  • King Gator
  • Posts: 3619
  • (x-in)->[process]->(y-out) ... simples!
Re: Mixed/Managed C++ dll's, passing objects.
« Reply #17 on: September 17, 2009, 10:00:05 PM »
Ok, I'm not having much luck here with ObjectIds.

I want to pass back and forth object ids, I have tried ObjectIdCollection-> AcDbObjectIdArray without much luck and erronous reults at best.

What would be the best way to pass an ObjectId[] to C++ and then pass an AcDbObjectIdArray* back to .net??

thanks.
"Short cuts make long delays,' argued Pippin.”
J.R.R. Tolkien

MickD

  • King Gator
  • Posts: 3619
  • (x-in)->[process]->(y-out) ... simples!
Re: Mixed/Managed C++ dll's, passing objects.
« Reply #18 on: September 17, 2009, 11:02:23 PM »
I've made a work around for now by iterating though the collection and adding each id to an AcDbObjectId array with the GETOBJECTID macro, seems to work so far.

I'd say I'll need to do the reverse to send it back.
"Short cuts make long delays,' argued Pippin.”
J.R.R. Tolkien

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8659
  • AKA Daniel
Re: Mixed/Managed C++ dll's, passing objects.
« Reply #19 on: September 17, 2009, 11:21:01 PM »
how about something like this 

Code: [Select]
static void ToIdArray
 (Autodesk::AutoCAD::DatabaseServices::ObjectIdCollection ^col , AcDbObjectIdArray &ids)
 {
  ids.append(*(AcDbObjectIdArray*)col->UnmanagedObject.ToPointer());
 }

 static Autodesk::AutoCAD::DatabaseServices::ObjectIdCollection
   ToIdCol (AcDbObjectIdArray &ids)
 {
  Autodesk::AutoCAD::Runtime::DisposableWrapper::
   Create(Autodesk::AutoCAD::DatabaseServices::ObjectIdCollection::typeid,
     IntPtr(ids.asArrayPtr()),false);
 }

MickD

  • King Gator
  • Posts: 3619
  • (x-in)->[process]->(y-out) ... simples!
Re: Mixed/Managed C++ dll's, passing objects.
« Reply #20 on: September 17, 2009, 11:30:18 PM »
I'm just using the mdginterop.h macro in a loop like this -

Code: [Select]
_ids->append (GETOBJECTID(col[i]))
and it's working ok.

What you have there may explain why I was getting over a million object added :roll:  :)
I'll give it a go when I get time as it's more elegant, I've got other fish to fry atm.

thanks again Daniel.
"Short cuts make long delays,' argued Pippin.”
J.R.R. Tolkien

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8659
  • AKA Daniel
Re: Mixed/Managed C++ dll's, passing objects.
« Reply #21 on: September 17, 2009, 11:36:36 PM »
lots of fun  :laugh:

MickD

  • King Gator
  • Posts: 3619
  • (x-in)->[process]->(y-out) ... simples!
Re: Mixed/Managed C++ dll's, passing objects.
« Reply #22 on: November 08, 2009, 07:35:41 PM »
Hey Dan,
how do I change an ObjectIdCollection to an ObjectIdCollection^ ??

Basically this is what I need -
Code: [Select]
ObjectIdCollection^ DCS3D::HlrEngine::Engine::GetVisibleLines()
{
ObjectIdCollection^ ids = //convert AcDbObjectIdArray to ObjectIdCollection^// ;
return ids;
}

These funny new symbols are confusiing in their use :roll: :)
"Short cuts make long delays,' argued Pippin.”
J.R.R. Tolkien

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8659
  • AKA Daniel
Re: Mixed/Managed C++ dll's, passing objects.
« Reply #23 on: November 08, 2009, 08:16:16 PM »
Sorry Mick, the first example I gave you of converting an AcDbObjectIdArray to ObjectIdCollection was wrong  :-o

try this one  :laugh:

Code: [Select]
static Autodesk::AutoCAD::DatabaseServices::ObjectIdCollection ^ToIdCol (AcDbObjectIdArray &ids)
 {
   return (ObjectIdCollection^)Autodesk::AutoCAD::Runtime::DisposableWrapper::
   Create(Autodesk::AutoCAD::DatabaseServices::ObjectIdCollection::typeid,
   IntPtr(ids.asArrayPtr()),false);
 }

MickD

  • King Gator
  • Posts: 3619
  • (x-in)->[process]->(y-out) ... simples!
Re: Mixed/Managed C++ dll's, passing objects.
« Reply #24 on: November 08, 2009, 08:28:48 PM »
Thanks Dan, that compiled fine, I'll do some testing and get back with the results, cheers.
"Short cuts make long delays,' argued Pippin.”
J.R.R. Tolkien

MickD

  • King Gator
  • Posts: 3619
  • (x-in)->[process]->(y-out) ... simples!
Re: Mixed/Managed C++ dll's, passing objects.
« Reply #25 on: November 08, 2009, 08:59:28 PM »
hmm, the output from the C# side is jibberish...

here's what I call from C# -
Code: [Select]
//engine is the C++ wrapper class.
ObjectIdCollection visIds = engine.GetVisibleLines();
                foreach (ObjectId id in visIds)
                {
                    ed.WriteMessage(id.ToString() + " ");
                }

here's what I have in my wrapper C++ class -

Code: [Select]
// helper function to convert native to managed id collections
ObjectIdCollection^ DCS3D::HlrEngine::Engine::ToIdCol (AcDbObjectIdArray *ids)
 {
return (ObjectIdCollection^)Autodesk::AutoCAD::Runtime::DisposableWrapper::
Create(Autodesk::AutoCAD::DatabaseServices::ObjectIdCollection::typeid,
    IntPtr(ids->asArrayPtr()),false);
 }

ObjectIdCollection^ DCS3D::HlrEngine::Engine::GetVisibleLines()
{
ObjectIdCollection^ ids = ToIdCol(_idsVis);  //  = AcDbObjectIdArray *_idsVis
return ids;
}

I'm missing something simple but can't put my finger on it...
"Short cuts make long delays,' argued Pippin.”
J.R.R. Tolkien

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Mixed/Managed C++ dll's, passing objects.
« Reply #26 on: November 08, 2009, 09:36:09 PM »

I'm holding my breath, 'cause I know what this is for :)
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

MickD

  • King Gator
  • Posts: 3619
  • (x-in)->[process]->(y-out) ... simples!
Re: Mixed/Managed C++ dll's, passing objects.
« Reply #27 on: November 08, 2009, 09:56:48 PM »
I gave away too many clues!

yep, almost there Kerry, this is the last hurdle (I hope) ;)
"Short cuts make long delays,' argued Pippin.”
J.R.R. Tolkien

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8659
  • AKA Daniel
Re: Mixed/Managed C++ dll's, passing objects.
« Reply #28 on: November 09, 2009, 02:01:58 AM »
Geez,
sorry about that, it seems if you create the AcDbObjectIdArray on the stack, it will blowup. DisposableWrapper::Create, wants the object to be in the heap.. :mrgreen:

try this out

Code: [Select]
//interop
Autodesk::AutoCAD::DatabaseServices::ObjectIdCollection ^ToIdCol (const AcDbObjectIdArray &ids)
{
 AcDbObjectIdArray *ptr = new AcDbObjectIdArray();
 ptr->append(ids);
 return dynamic_cast<ObjectIdCollection^>(DisposableWrapper::
    Create(ObjectIdCollection::typeid,(IntPtr)ptr,true));
}

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8659
  • AKA Daniel
Re: Mixed/Managed C++ dll's, passing objects.
« Reply #29 on: November 09, 2009, 02:06:24 AM »
the test

C++
Code: [Select]
ObjectIdCollection^ Wrapper::getPointIds( void )
 {
  ads_name ssname;
  ObjectIdCollection^ col = nullptr;

  if(acedSSGet(NULL,NULL,NULL,NULL,ssname) != RTNORM)
   return nullptr;

  AcDbObjectIdArray ids;

  if(acedGetCurrentSelectionSet(ids) != eOk)
  {
   acutPrintf(_T("\nfail"));
   acedSSFree(ssname);
   return nullptr;
  }

  col = ToIdCol(ids);
  acedSSFree(ssname);
  return col;
 }

C#
Code: [Select]
[CommandMethod("doit")]
  static public void doit()
  {
   foreach(ObjectId id in MdgMick.Wrapper.getPointIds())
   {
     AcAp.Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("{0}", id);
   }
  }