ObjectARX
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

passing string to custom objects through a managed wrapper

13 REPLIES 13
SOLVED
Reply
Message 1 of 14
ChaosInACT
1133 Views, 13 Replies

passing string to custom objects through a managed wrapper

I'm working on a mixed code project - Custom DBX objects wrapped and used in vb.net, ala polysamp or even simplesquare examples.

 

I've got most things going good - lot of work but still, it's going. oddly one of the harder things to do is pass string data into the wrapper due to the curse of unicode.  I'm sure there is a way to do this (i've seen the StringToWchar and WcharToString functions but failed to get use out of them).

 

Anyhow anyone got advice on this? I'll put all the (relavent) code below:

 

The variable in the custom object class:

 

const wchar_t* m_Suburb;

 

the get / set declarations in the class:

 

std::string getSuburb();
Acad::ErrorStatus setSuburb(std::string Suburb);

 

and [my attempts at] the definitions for them:

 

std::string SectionObject::getSuburb()
{

std::wstring ws;
ws = m_Suburb;
std::string str(ws.begin(),ws.end());
return str;
}

 

Acad::ErrorStatus SectionObject::setSuburb(std::string Suburb )
{
std::wstring widestr = std::wstring(Suburb.begin(), Suburb.end());

const wchar_t* widecstr = widestr.c_str();
m_Suburb=widecstr;
return Acad::eOk;
}

 

and the declaration for the wrapper of the property:

 

property std::string Suburb
{
std::string get ();
void set(std::string suburb);
}

 

...the definition of the wrapper:

 

std::string BCHF::SectionObjectWrap::mgSectionObject::Suburb::get()
{
return (GetImpObj()->getSuburb());
}

 

void BCHF::SectionObjectWrap::mgSectionObject::Suburb::set(std::string value)
{
Autodesk::AutoCAD::Runtime::Interop::Check(GetImpObj()->setSuburb(value));
}

 

 

 

and the only other relavent thing is the initialization in the constructor:

 

SectionObject::SectionObject () : m_SectNumber(1)
, m_Suburb(_T("s"))//<- here is the init for string - this i'm really making up, no idea how to initialize a wchar....
, m_ShowSectNumber(false)
, m_ShowArea(false)
, m_TxtMspace(0,0,0)
, m_TxtSizeMspace(0.0)
, m_Normal(0,0,1)
, m_pManaged(NULL) {
}

 

anyone else been here? I can't find much discussion about this, so any ideas appreciated 🙂

oh, and is there anyone to disable these smiley faces in code snippets?!?!? lol.

 

13 REPLIES 13
Message 2 of 14
ChaosInACT
in reply to: ChaosInACT

ok...thanks to Balaji I've got a start - PolySamp has it burried in there 🙂

 

now.... When I try to USE the polysamp example, it gives me grief. Largely (I suspect) because I modeled after SimpleSquare originally.

 

I'm being told this notation:

 

__property void set_Name(String* value);
__property String* get_Name();

 

is illegal in visual studio - and when I try to adapt polysamp to :

 

property String* Suburb

{
String* get ();
void set( String* suburb);
}

 

I get a bunch of:

"an ordinary pointer to a c++/cli reference is not aloud"

 

Wah. I was so close.

 

I'm also getting a lot of errors on StringToCIF and CIFToString - 

but one thing at a time....

 

i noticed that the declarations have a "ref" in simple square class and a "__gc" in Polysamp - maybe this is the diffence, no idea.

I had the whole thing working with the old notation - I'm looking at re-writing the whole thing to pass a string?!? there has to be an eaiser way :S

 

Message 3 of 14
Balaji_Ram
in reply to: ChaosInACT

Hi Carl,

 

The Polysamp SDK sample uses the old CLR syntax. 

 

You can find the changes to migrate it to the new clr syntax here :

http://msdn.microsoft.com/en-us/library/b23b94s7(v=vs.90).aspx

 

From that article, you can find that the String* is to be replace with String^

I have attached the SimpleSquare sample with the changes to pass a String.

 

I have only verified that it builds ok. I haven't tested it, so please do let me know if there is a problem and if does not work.

 

Regards,

Balaji



Balaji
Developer Technical Services
Autodesk Developer Network

Message 4 of 14
ChaosInACT
in reply to: Balaji_Ram

Thanks AGAIN for the push.

 

I'm not even kinda kidding, there are tears in my eyes right now;

 

my co-workers couldn't take anymore swearing either 😉

Message 5 of 14
Balaji_Ram
in reply to: ChaosInACT

Sorry for the trouble. I am glad you have a sample to work on.

 

Both the samples, SimpleSquare and PolySamp are examples which were originally implemented using the Old CLR syntax. I migrated the SimpleSquare to use the new CLR syntax and post it in the ADN Devblog. But the Polysamp is not yet migrated and continues to use the old CLR syntax. So this can cause some trouble when portions from the managed wrapper of Polysamp are used. 

 

The MSDN link that I posted earlier should be a helpful reference in case you need to migrate such code in future.

 

Regards,

Balaji

 

 

 

 

 

 

 

 

 



Balaji
Developer Technical Services
Autodesk Developer Network

Message 6 of 14
ChaosInACT
in reply to: Balaji_Ram

"Sorry for the trouble. I am glad you have a sample to work on."

 

lol very very true. while uh...a bit...out of date, without the samples these projects would simply be impossible. A collegue of mine and I were actually joking the other day about what these projects would be like without internet access...But I digress.

 

While I'm absolutely giving Balaji 100% credit for this save/solution, I'm going to post the final working syntax [that compiled for me. I haven't tested it much yet] here and flag it as the solution to help any other weary travellers in the future.

 

So here it is:

 

//the string internal variable declaration in your custom class:

TCHAR*  myPassedString;

 

//the get / set function declarations in your custom class:

const TCHAR* getMyPassedString() const;
Acad::ErrorStatus setMyPassedString(const TCHAR* myPassedString);

 

//the get / set function definitions in your custom class:

 

 

const TCHAR* myCustomClass::getMyPassedString() const
{
assertReadEnabled();
return myPassedString;
}

 

Acad::ErrorStatus myCustomClass::setMyPassedString(const TCHAR* value)
{
assertWriteEnabled();

acutDelString(myPassedString);
myPassedString= NULL;

if(value!= NULL)
{
acutUpdString(value, myPassedString);
}

return Acad::eOk;
}

 

 

/*HERE IS THE TRICKY BIT!!!! The Declaration for the Wrapper for the Custom Object

//>>>>pay attention to the new property notation, and that ^ has replaced the spots you would expect a *. <<<<<

//in a way it was staring me in the face from:

//    void add (SectionModifiedHandler^);

// but things like this in the wrapper:

//    inline SectionObject*  GetImpObj()

// do seem inconsistent...also the .NetWrapper Wizard uses the depreciated, and in VS2012, killed __property notation.

// it won't work in 2012 but seems to be working in 2010 in the sample - 2012 never even liked opening PolySamp at all -

// probably due to the removal of free "installers" from the Visual Studio suite.*/

 

property String^ MyPassedString

{
String^ get();
void set(String^ value);
}

 

//the definition for the Wrapper:

//get

String^ ADSY::ClassWrapNamespace::myCustomClass::MyPassedString::get()
{
return CIFToString(GetImpObj()->getMyPassedString());
}

//set

void ADSY::ClassWrapNamespace::myCustomClass::MyPassedString::set(String^ value)

{
Autodesk::AutoCAD::Runtime::Interop::Check(GetImpObj()->setMyPassedString(StringToCIF(value)));
}

 

 

 

__________________________________________________________________________________________________________

I've just included the relavent things to passing strings, and the class/variable names I've changed to make everything more clear... 🙂 hope that helps someone.

 

 

Message 7 of 14
owenwengerd
in reply to: ChaosInACT

You don't need acutDelString() or the other gymnastics. The acedUpdString() function already does that for you.

--
Owen Wengerd
ManuSoft
Message 8 of 14
ChaosInACT
in reply to: owenwengerd

I'm happy to ammend it... a lot of what I'm reading seems outdated, but just to clarify, from the dev handbook begining, tips and techniques (and the sample itself):

 

Freeing Strings Returned as Non-const Pointers

When calling methods that return non-const string pointers (for example, AcDbSymbolTable::getName(char&* pName)), you should free the memory occupied by the returned string. For example:

 

// The getName() call should be followed by a call to
acutDelString(pLtName);pLtTableRcd->getName(pLtName);
// ... other code
acutDelString(pLtName);

 

so is that wrong now or just fluff...?

Message 9 of 14
Balaji_Ram
in reply to: ChaosInACT

Hi Carl,

 

There is also an overload that uses AcString which is more convenient to use.

There is no need to cleanup if you create an AcString instance on the stack.

 

Regards,

Balaji



Balaji
Developer Technical Services
Autodesk Developer Network

Message 10 of 14
loic.jourdan
in reply to: ChaosInACT

AcString versions are indeed somewhat more convenient but beware that there is a bug in AcString version of AcDbBlockTableRecord::getName (see http://forums.autodesk.com/t5/Autodesk-ObjectARX/AcDbBlockTableRecord-getName-two-signatures-differe...

My two cents
----
20-20 CAD / 20-20 Technologies
Message 11 of 14
owenwengerd
in reply to: ChaosInACT


@Anonymous wrote:

so is that wrong now or just fluff...?


I don't see any problem with that sample code; my comment applies only to your code.

--
Owen Wengerd
ManuSoft
Message 12 of 14
ChaosInACT
in reply to: loic.jourdan

I'm getting a bad url link there?

Message 13 of 14
loic.jourdan
in reply to: ChaosInACT

here is the link, sorry

----
20-20 CAD / 20-20 Technologies
Message 14 of 14
ChaosInACT
in reply to: loic.jourdan

🙂 Thanks!

 

Actually your doing me the favor, so no apology needed.

 

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost