TheSwamp

Code Red => .NET => Topic started by: MickD on September 13, 2009, 09:34:28 PM

Title: Mixed/Managed C++ dll's, passing objects.
Post by: MickD on September 13, 2009, 09:34:28 PM
It's been a while since I played with mixed/managed C++ and I tried to avoid it by using native arx to handle user input etc. but now I need to do things in a better fashion to make my dll more of a library instead of an application addon.

How would 'you' pass objects like acad pointers such as db's, entities and object id arrays.

Any tips/clues/tricks/samples would be great.

Thanks,
Mick.
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: MickD on September 13, 2009, 09:41:04 PM
for example, this compiles -
Code: [Select]
void MyApp::MyLib::Utils::SetDb(Database* db)
{
if(db != NULL)
{
_pDb = (reinterpret_cast<AcDbDatabase*>(&(db)));
}
}

but so does this -
Code: [Select]
void MyApp::MyLib::Utils::SetDb(Database* db)
{
if(db != NULL)
{
_pDb = (reinterpret_cast<AcDbDatabase*>(&(db->UnmanagedObject)));
}
}

and is this way of passing objects the most elegant??
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: It's Alive! on September 13, 2009, 09:52:59 PM
does this compile?

Code: [Select]
void MyApp::MyLib::Utils::SetDb(Database^ db)
{
  if(db != nullptr)
   {
     _pDb =  reinterpret_cast<AcDbDatabase*>(db->UnmanagedObject);
   }
}
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: MickD on September 13, 2009, 10:01:00 PM
hmmm, changed the properties to /clr instead of /clr oldsyntax and I now have a swag of '*' errors in my other code, but that part seemed to compile :)

there's also a swag of deprecated errors, may need to set this one up again from scratch...

Do you have a favourite tutorial on this stuff Daniel I could brush up on?

Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: It's Alive! on September 13, 2009, 10:04:52 PM
Ah sorry, your using the old syntax. which would you prefer using?
What version of Acad are you targeting?
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: MickD on September 13, 2009, 10:14:42 PM
2k7 and up, I guess the newer syntax may make it easier to see what's managed and what's not (??)
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: It's Alive! on September 14, 2009, 02:49:54 AM
I would use the new coding style. I don't know of too many tutorials covering this,
but I have a lot of samples wrapping native code I can send to you. I'm not sure what your end goal is.
Are you wrapping native stuff?  who is the consumer of your library, .NET or native?


Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: MickD on September 14, 2009, 05:57:17 AM
I'm wrapping native stuff for use in .net rather than using P/Invoke. I have my class/s all sorted out for the mixed/managed part, just need to handle the marshalling of the objects to be dealt with between .net and my m/m dll.

I'll pm you with further info Daniel if needed but I thought it would be helpful for others as well. For instance, if you have some methods that would benefit from the use of native code to speed things up this type of back and forth protocol is very handy.

It's been a while and my C++/CLI is very basic and I still suffer from straight C tendencies but I'll have to deal with those if I want to get this done properly :)
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: It's Alive! on September 14, 2009, 08:48:55 AM
...I thought it would be helpful for others as well..

Absolutely! let me dig for a few samples
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: It's Alive! on September 14, 2009, 10:45:06 AM
Lets where to start, Of course basic types (int, double...) we don't need to anything special.
here are a couple of samples doing strings and arrays, note I prefer using the CString for the strings and Marshal::Copy for arrays

Code: [Select]
static void ArxMdg_doit1(void)
 {
  CString cstr = _T("To Managed and back");
  System::String ^str = gcnew System::String(cstr);
  acutPrintf(CString(str));
 }


 static void ArxMdg_doit2(void)
 {
  TCHAR *tchar = _T("To Managed and back");
  System::String ^str = gcnew System::String(tchar);
  pin_ptr<const TCHAR> pstr = PtrToStringChars(str);
  acutPrintf(pstr);
 }

 static void ArxMdg_doit3(void)
 {
  double npt[3] = {10.0,100.0, 1000.0};
  array<double> ^mpt = gcnew array<double>(3);

  System::Runtime::InteropServices::Marshal::Copy
     ( System::IntPtr(&npt[0]),mpt, 0, mpt->Length);

  acutPrintf(_T("%g, %g ,%g"),mpt[0], mpt[1], mpt[2]);
 }

 static void ArxMdg_doit4(void)
 {
  array<double> ^mpt = gcnew array<double>{10.0,100.0, 1000.0};
  pin_ptr<const double> npt = &mpt[0];
  acutPrintf(_T("%g, %g ,%g"),npt[0], npt[1], npt[2]);
 }
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: It's Alive! on September 14, 2009, 11:02:51 AM
Next, let's play with value classes, objects that we want to use on the stack.

.h
Code: [Select]
#pragma once
#pragma managed(push, off)
class CNative
{
 LONG_PTR m_num;
public:
 CNative(LONG_PTR val);
 ~CNative(void);
  bool isNull(void);
  bool isGreaterThan(LONG_PTR val);
  bool isLuckySeven(void);
  LONG_PTR Num() const { return m_num; }
  void Num(LONG_PTR val) { m_num = val; }
};
#pragma managed(pop)

.cpp
Code: [Select]
#include "StdAfx.h"
#include "Native.h"

CNative::CNative(LONG_PTR val):m_num(val){}
CNative::~CNative(void){}

bool CNative::isNull( void )
{
 return this->m_num == NULL;
}

bool CNative::isGreaterThan( LONG_PTR val )
{
  return this->m_num > val;
}

bool CNative::isLuckySeven( void )
{
 return this->m_num == 7L;
}


now the managed wrapper

.h
Code: [Select]
#pragma once
#include "Native.h"
using namespace System;

#define UNMNGD_CLASS(X) (*reinterpret_cast<CNative*>(&(X)))

namespace ArcMdg
{
 public value class CManaged
 {
  LONG_PTR m_num;

 public:
  CManaged(LONG_PTR val);
  CManaged(const CNative *native);

  bool isGreaterThan(LONG_PTR val)
  {
   return UNMNGD_CLASS(*this).isGreaterThan(val);
  }

  property bool isNull
  {
   bool get() { return UNMNGD_CLASS(*this).isNull() ; }
  }

  property bool isLuckySeven
  {
   bool get() { return UNMNGD_CLASS(*this).isLuckySeven() ; }
  }

  virtual System::String^ ToString() override;
 };
}

.cpp
Code: [Select]
#include "StdAfx.h"
#include "Managed.h"

namespace ArcMdg
{
 CManaged::CManaged(LONG_PTR val) : m_num(val)
 {
 }

 CManaged::CManaged( const CNative *native )
 {
  m_num = native->Num();
 }

 System::String^ CManaged::ToString()
 {
  return String::Format("{0}", m_num);
 }
}
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: It's Alive! on September 14, 2009, 11:05:29 AM
and the test

Code: [Select]
static void ArxMdg_doit5(void)
 {
   CNative n(7);
   ArcMdg::CManaged m(&n);

   if(m.isLuckySeven)
    acutPrintf(_T("\nisLuckySeven"));

    if(m.isGreaterThan(2))
     acutPrintf(_T("\nisGreaterThan 2"));

    acutPrintf(_T("\nand the value is %s "), CString(m.ToString()));
 }

Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: MickD on September 14, 2009, 05:17:21 PM
Thanks Dan, let me soak that in for a bit. :)
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: MickD on September 14, 2009, 06:54:29 PM
Ok, I think I've got the managed to native ok, I'm still stuck on the native to managed though, I'd like to pass back managed objects so it's seemless on the .net side.

here's what I have so far but the native to managed methods don't work but should give an idea of what I want to achieve.
Code: [Select]
// mixman.h

#pragma once

using namespace System;
using namespace Autodesk::AutoCAD::ApplicationServices;
using namespace Autodesk::AutoCAD::DatabaseServices;
using namespace Autodesk::AutoCAD::Runtime;

// conversions from managed to native:
#define GETDB(database) (*reinterpret_cast<AcDbDatabase*>(&(database)))
#define GETIDARRAY(objidarray) (*reinterpret_cast<AcDbObjectIdArray*>(&(objidarray)))

// conversion functions from native to managed:
inline Database SetMgdDatabase ( AcDbDatabase* pDb)
{
Database db =  gcnew Database(pDb);
return db;
}
inline ObjectIdCollection SetIdCollection(AcDbObjectIdArray* nativeArray)
{
ObjectIdCollection idcoll = gcnew ObjectIdCollection(nativeArray);
return idcoll;
}
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: It's Alive! on September 14, 2009, 07:23:15 PM
I think you need to use DisposableWrapper::Create. Most all AutoCAD's managed classes derive from this. 
Try these


Code: [Select]
inline Database^ SetMgdDatabase ( AcDbDatabase* pDb)
{
 return (Database^)DisposableWrapper::
  Create(Database::typeid, IntPtr(pDb),false);
}

inline ObjectIdCollection^ SetIdCollection(AcDbObjectIdArray* nativeArray)
{
 return (ObjectIdCollection^)DisposableWrapper::
  Create(ObjectIdCollection::typeid, IntPtr(nativeArray),false);
}
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: MickD 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 :)
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: It's Alive! 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.
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: MickD 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.
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: MickD 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.
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: It's Alive! 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);
 }
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: MickD 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.
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: It's Alive! on September 17, 2009, 11:36:36 PM
lots of fun  :laugh:
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: MickD 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: :)
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: It's Alive! 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);
 }
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: MickD 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.
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: MickD 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...
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: Kerry on November 08, 2009, 09:36:09 PM

I'm holding my breath, 'cause I know what this is for :)
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: MickD 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) ;)
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: It's Alive! 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));
}
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: It's Alive! 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);
   }
  }

Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: MickD on November 09, 2009, 04:54:37 AM
Thanks Daniel, I wont get a chance to test for a day or so as I have other commitments but it looks good.
I'm squeesing this coding in between jobs so I really appreciate your help here, I feel a bit guilty for not putting in the study learning the clr stuff but I really only need these few pieces to get me through so again, thanks heaps, I owe you a beer or three :)
cheers.
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: MickD on November 10, 2009, 09:37:35 PM
Thanks Daniel, works a treat now, cheers :)

Kerry, I'll send you something soon ;)
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: Kerry on November 10, 2009, 09:56:27 PM

Take your hurry. (translated : in your own time ... I used to have an Irish neighbour when I was a kid.)

Thanks Mick.






Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: It's Alive! on November 10, 2009, 10:30:10 PM
Thanks Daniel, works a treat now, cheers :)

Great! please send beer or black licorice to:

Lane 99 PuMing Rd. Bldg #26 Apt#1403
Shanghai, China, 200120

 JK :-D
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: It's Alive! on November 11, 2009, 02:58:27 AM
Never mind, I just found a small box of Good&Plenty, an extremely rare item in this part of the world.. ah bliss  :love:
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: Kerry on November 11, 2009, 03:27:13 AM

I'll get some Darell Lee in to a bag :)

.. and some Rocklea Road ??
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: It's Alive! on November 11, 2009, 05:54:45 AM

I'll get some Darell Lee in to a bag :)

.. and some Rocklea Road ??

Ah YES! Please send me the bill too  :wink:
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: Kerry on November 12, 2009, 03:38:19 AM

The carton is packed and addressed  ... in the mail tomorrow.

there is a bonus of some earwax flavoured jelly beans to try :)

.. will take a couple of days to reach you.

In appreciation !



Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: It's Alive! on November 13, 2009, 05:13:38 AM
Wow! Awesome! Thank you!
I will reciprocate with goodies I have found over here!   :kewl:
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: csharpbird on November 15, 2009, 02:56:51 AM
Hi,Daniel
How to covert a managed ResultBuffer object to an unmanaged resbuf?
How to covert an unmanaged resbuf object to a managed ResultBuffer?
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: It's Alive! on November 15, 2009, 03:56:45 AM
Pretty much the same way, if wrapper derives from Autodesk.AutoCAD.Runtime.DisposableWrapper, you can use the methods Create and get_UnmanagedObject


Code: [Select]
resbuf *pRb = reinterpret_cast<resbuf*>(resultBuffer->UnmanagedObject.ToPointer());

//and

ResultBuffer ^resultBuffer =
  dynamic_cast<ResultBuffer^>(DisposableWrapper::Create(ResultBuffer::typeid,(IntPtr)pRb,false));
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: MickD on January 14, 2010, 09:05:02 PM
Hi Dan,
I've been pulling my hair out wondering why I can't get this finished :(
then I started looking at what I was passing around, I removed all the managed params and it worked fine so I looked a bit closer at what the conversion macros provided in the sdk were doing and I was getting mixed results.

Anyway, I've decided to do these conversions myself so I started with the snippet above but it errors out with 'UnManagedObject is not a member of .....blah blah'

Here's what I have

AcGePoint3d* p1 = reinterpret_cast<AcGePoint3d*>(pnt1->UnmanagedObject.ToPointer());

where pnt1 is passed in as Point3d^

the macro from adsk is -

#define GETPOINT3D(point3d) (*reinterpret_cast<AcGePoint3d*>(&(point3d)))

If I pass it a straight Point3d it spits out 0,0,0 regardless of point data, if I use a Point3d^ it spits out something like 33568899003 (a memory address or garbage??).

So, how is the best way to convert it to native, thanks.
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: MickD on January 14, 2010, 09:54:15 PM
Doh!!

I changed it to Point3d (without the ^) in my params and the arx macros works fine.

Sheesh, some consistency would be nice :roll:
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: It's Alive! on January 14, 2010, 10:14:24 PM
 :lol:  well I made these for you

Code: [Select]
void Wrapper::NativeToManaged()
 {
   AcGePoint3d npnt(1,1,1);//stack
   AcGePoint3d *pnpnt = new AcGePoint3d(2,2,2);//heap

   Point3d mpnt1 =  ToPoint3d( npnt );
   acutPrintf(_T("\n%g,%g,%g"),mpnt1.X,mpnt1.Y,mpnt1.Z);

   Point3d mpnt2 =  ToPoint3d( *pnpnt );
   acutPrintf(_T("\n%g,%g,%g"),mpnt2.X,mpnt2.Y,mpnt2.Z);

   Point3d ^pmpnt1 =  %ToPoint3d( npnt );
   acutPrintf(_T("\n%g,%g,%g"),pmpnt1->X,pmpnt1->Y,pmpnt1->Z);

   Point3d ^pmpnt2 =  %ToPoint3d( *pnpnt );
   acutPrintf(_T("\n%g,%g,%g"),pmpnt2->X,pmpnt2->Y,pmpnt2->Z);

   delete pnpnt;
 }

 void Wrapper::ManagedToNative()
 {
   Point3d mpnt(3,3,3); //stack
   Point3d ^pmpnt = gcnew  Point3d(4,4,4);//heap

   AcGePoint3d npnt1 =  GETPOINT3D( mpnt );
   acutPrintf(_T("\n%g,%g,%g"),npnt1.x,npnt1.y,npnt1.z);

   AcGePoint3d npnt2 =  GETPOINT3D( (Point3d)*pmpnt );
   acutPrintf(_T("\n%g,%g,%g"),npnt2.x,npnt2.y,npnt2.z);

   AcGePoint3d *pnpnt1 =  &GETPOINT3D( mpnt );
   acutPrintf(_T("\n%g,%g,%g"),pnpnt1->x,pnpnt1->y,pnpnt1->z);

   AcGePoint3d *pnpnt2 =  &GETPOINT3D( (Point3d)*pmpnt );
   acutPrintf(_T("\n%g,%g,%g"),pnpnt2->x,pnpnt2->y,pnpnt2->z);
 }
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: It's Alive! on January 14, 2010, 10:21:39 PM
I would try to keep those value types on the stack so you're not running into pinning pointers and stuff. 
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: MickD on January 14, 2010, 10:23:28 PM
woot! Thanks Dan.

Just having trouble with the database now, I'm passing in a Database^, this is what I have -

#define GetDb(database) (reinterpret_cast<AcDbDatabase*>(&(database)))

but no worky

this mixed/managed stuff has sooo many subtle tricks to watch out for, I'm almost there though!
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: It's Alive! on January 14, 2010, 10:32:21 PM
The casting only works for managed value types. for ref types you need to do something like   


Code: [Select]
AcDbDatabase *pnDb =  pmDb->UnmanagedObject.ToPointer();

//and

Database ^pmDb = dynamic_cast<Database^>(DisposableWrapper::Create(Database::typeid,(IntPtr)pnDb,false));
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: MickD on January 14, 2010, 10:40:38 PM
hmm, I think I'm getting the db ok but as I'm creating a new one in C# I think it's open for write and I'm trying to add abjects to it in native code, I'll dig a bit deeper and let you know, thankis again :)
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: It's Alive! on January 14, 2010, 10:51:16 PM
Cool! May your pointers all point to the same instance  :lol:
Title: Re: Mixed/Managed C++ dll's, passing objects.
Post by: MickD on January 14, 2010, 10:57:10 PM
woot!

Thanks Daniel, working fine now with a small adjustment, cheers.

pDb = (AcDbDatabase*)dbout->UnmanagedObject.ToPointer();