Hi all,
I have been experimenting building a native solution and have a few questions, hopefully someone might be able to give some advice to save me pulling any more hair out!
Really hoping to figure out these last few pain points, as I think that a mixed language solution would provide the best of both worlds for Microstation development provided I can sort out these last few teething issuesThanks!
Ed
Hi Ed,
Edward Ashbolt said:I have been experimenting building a native solution
It's a bit weird you wrote you experiment with native solution and in the first question you mention CLR class, which is "by definition" NET object. Maybe naming confusion, because you mix native code with C++/CLI, which is standard NET assembly?
Maybe it would make more sense when you do not use "CLR class" term (because it's very general) and exactly specify what you want to achieve using what langauge (C#, able to produce pure code or C++/CLI producing mixed code).
Edward Ashbolt said:hopefully someone might be able to give some advice to save me pulling any more hair out!
To keep your hairs intacted, think about your question as based on misunderstanding of core concepts, so even though they can be answered, they sounds weird.
Edward Ashbolt said:Is it possible to build a CLR class library and load that in Microstation, without the use of bmake?
Let's assume you do not think CLR class library, but NET assembly created using C++/CLI. Such assembly is nothing special, and bmake does not anything magical, so yes, you can create such assembly (which contains mixed CIL code) even manually. bmake does nothing else than it calls other tools, using command line, one by one, with correct parameters.
Edward Ashbolt said:is it possible to create a CLR solution and reference/call my own .NET class library?
C++/CLI PRODUCES NET assembly (and not native dll), so it can reference, and can be referenced, by any other NET project, based on any NET langauge.
Edward Ashbolt said:I managed to build a C++ MDL with command table etc. but as soon as I make a call to any .NET methods it fails to compile with error "System::Object not found, missing /clr option or missing import of standard assemblies?".
Please explain exactly what you want to achieve, or better, to share your code. C++/CLI is typically used to wrap native code and publish NET API (in this way, the most of MicroStation NET API is implemented). I guess an opposite direction (wrap NET API to be called from native) would be also possible, but I do not recall any such example (probably it's rare requirement).
Edward Ashbolt said:Is it possilble to use XML to define the command table in C++, similar to C#?
No. C++ has own system to define command table, based on MicroStation resources. In fact, two different mechanisms exist in native code: class command table and XCommands.
Regards,
Jan
Bentley Accredited Developer: iTwin Platform - AssociateLabyrinth Technology | dev.notes() | cad.point
Unfortunately, Bentley Systems have evolved two different and incompatible technologies to define and implement a command table.
However, it should be possible to write an XLS transformation that would convert the .NET XML command table into a C++ resource source table. Then we could write an XML command table, irrespective of the technology chosen to build the application.
Regards, Jon Summers LA Solutions
Thanks Jan,
I haven't done much with C++ yet... hence my limited knowledge! To elaborate further:
Jan Šlegr said:you experiment with native solution and in the first question you mention CLR class, which is "by definition" NET object
My (probably incorrect) understanding was that CLI / CLR were essentially the same thing, for writing native C++ code that could interact with .NET classes. I guess I'm just confused though
Jan Šlegr said:Please explain exactly what you want to achieve
What I was trying to achieve was a mixed language solution, using C++ as my main "addin", and then execute either C++ or C# commands using a "command handler" method. My process was as follows:
#include <Mstn\MdlApi\MdlApi.h> #include <Mstn\ISessionMgr.h> #include <Mstn\MdlApi\mselems.h> #using <MyCSharpLib.dll> void CmdExecute(WCharCP unparsedP) { MyCSharpNamespace::HelloWorldManaged().Execute(); return; };
It would seem that it is possible to build a mixed language solution, at least according to this part of the wiki: https://communities.bentley.com/products/programming/microstation_programming/w/wiki/52410/writing-add-ins-in-c-cli
Regarding what you said earlier about CLI being a kind of .NET output, it is starting to make sense why this part of the wiki is under the header for managed code, and likely the reason I could not get this working properly within my native solution! The bit that confused me is that it still uses make files and C++ code so I assumed that it was native C++ with the added benefit of C# interoperability.
I like that idea, keeps it pretty simple!
Edward Ashbolt said:My (probably incorrect) understanding was that CLI / CLR were essentially the same thing
Well, they are, but they are something completely differnt than what you mean ;-)
But, I think we are discussing C++/CLI, which is (in fact proprietary) language, designed by Microsoft, adopting C++ to fit CLI specifications.
Edward Ashbolt said:What I was trying to achieve was a mixed language solution, using C++ as my main "addin", and then execute either C++ or C# commands using a "command handler" method
It would be possible, because C++/CLI is just a tool,. allowing to mix native and managed code, but I never tried to use it in this way (reasons below). You can find examples on Internet how to call managed code from native, using C++/CLI wrapper, on Internet, but I guess the most of examples for MicroStation is "an opposite way": How to call (missing) native functionality from NET code.
My question is why to do something like this? It's a plenty of work, requiring extra effort (C++/CLI is not intuitive language) for close-to-zero benefits. When you have C++ app (it's not "addin") for MicroStation, probably the only reason why to call anything from NET is GUI, that can be implemented using WPF. Plus, of course, when some 3rd party external NET library is required.
Edward Ashbolt said:My process was as follows
It is extremely complicated in my opinion. It's like "There are several areas, where I can do mistakes. So, I will use all of them together."
I would prefer to keep things as simple as possible. Use bmake and Visual Studio Code until functional result is obtained. Things like to integrate the whole system to (over)complex Visual Studio configuration can be benefit in future, but does not bring any extra value to a process of compilation (but can help with C++/CLI).
Edward Ashbolt said:The bit that confused me is that it still uses make files and C++ code so I assumed that it was native C++ with the added benefit of C# interoperability.
It is a huge misunderstanding (of several topics)!
With regards,
Thanks for a very detailed reply Jan! I will certainly heed your advice and keep things simple moving forward. I was hopeful that perhaps I could set this solution up in a simple way, keeping the .NET and C++ code separate except for when calling a C# command was required, however it seems that might be a lot more complicated than I first imagined... At least I learnt a lot in the process! Maybe I'll revisit a mixed language or C++ MDL solution in the future, but for now I think it would be best to stick with .NET API and keep things simple.
Thanks a lot for all the help,Ed
Edward Ashbolt said:however it seems that might be a lot more complicated than I first imagined..
\Well, crossing borders between managed and native is alwyas complex.
Often it requires to think a lot about memory management on both sides, because memory cannot be shared, so it's about proper allocation and freeing objects ... which leads to IDisposable interface on managed side.
On the other hand (what is my experience when I implemented wrappers around native functionality to be available in NET), it is "templated", so when you do first several projects, the next ones like mostly copy of concepts and structure.
Edward Ashbolt said:Maybe I'll revisit a mixed language or C++ MDL solution in the future
You can start with mixed code example, delivered with MicroStation SDK. It does not solves managed/native marshalling process, but shows how the project tiself looks like and how make file is done. It creates NET addin, written not in C#, but in C++/CLI.
Edward Ashbolt said:but for now I think it would be best to stick with .NET API and keep things simple.
Yes, NET is the simplest way (but with some API limitations and also slower a bit). C++ is the second one, because it is more complicated langauge ;-)
To chose one or second and to do not mix native and managed should always be preferred. But, when 95% of functionality can be done in NET, there is no reason to switch everything to C++, and C++/CLI can be used to solve these missing 5% ;-)
Thanks Jan, appreciate the advice. Definitely keen to explore C++ more in the future, for that 5% if/when I hit that road block!