ARCast.TV - Bridging The Gap from C++ to C#

The Discussion

  • User profile image
    rojacobs - Bridging The Gap from C++ to C#

    Announcer: It's Friday June 22nd 2007 and you're watching ARCast TV.
    Ron Jacobs: Hey welcome back to ARCast TV. This is your host Ron Jacobs. Remember there was a language a lot of us used to write and it was called C++? I know some of you are laughing because you're like I still write in that! C++ was around for a lot of years, I wrote a lot of C++ code, I'm sure many of you did. And for people who have a significant code base in C++, they want to find out, well, how can we move up forward, can we interopt between say, C++ and C# code or how can we call newer things in dotmap or call from dotmap to C++ code, what are the options and what are the ways in which we can get that done.

    It's a big concern for a lot of people and so today on ARCast we have got some help for you, this wonderful guy in Israel called Manu going to help us think about the ways in which we can bring these two worlds together. So listen up!

    Welcome back to ARCast. I'm your host Ron Jacobs and once again we are here in Tel Aviv and today I'm joined by Manu. Did I say that right, Manu?
    Manu Cohen-Yashar: Yes, Manu Cohen-Yashar.
    Ron: Great, tell me about yourself, Manu, what do you do here?
    Manu: Well I'm a senior consultant in the Sela Technology Center, and what I do is distributing applications and I'm doing applications security while distributing applications. So I'm in the distributed world.
    Ron: Today we want to talk about something that a lot of people think we are long past this, but there was a lot of code out there which was written in C++. I wrote lots of it myself and I know you probably did too. And not everybody has turned on to, switched everything to C# or whatever and so we are going to have to live with that code base for a long time to come. Now the question is, if I have my C++ code and maybe I'm writing some new stuff in C# and I want to call that C# code from C++, what do I have to do to make that work, what are my options?
    Manu: Well, this is not easy. The interoperability issue is not easy at all. If you are calling from C++ code, C# code you have to make sure that the CLR, MS SQL and DLL is on. You have to bring that DLL on. And what you can do, is first you can use the API of the CLR, so you can just call this CLR DLL and bring it up. But this is not easy.

    Second you can use C++ CLI, which was developed for this. But, again, this is another language, a complete other language. Now in your code base you will have to manage your C++ code, which is one language, the C# code which is another language, and the C++ CLI, which is a third language.

    So you have to have that knowledge in your company, which again is not that easy. And C++ CLI, which is an amazing language, it knows to leverage both the C++ non-managed memory management and the C# managed memory management. And it knows to switch between those two memory systems. And this is not so easy. This is why this language is so complex.

    Now the other option that you have is to use COM -- COM interoperability. But COM has its own issues, threading model of COM, and more and more issues. We have to install this COM, to register C# code, and sometimes it is not acceptable. So you are in a deep problem, my dear, if you want to use the C++ code to call the C# code, you are in quite an issue. And then there is WCF.

    If we go back and we think about the interoperability problem, we find out that there are two strains, two ways to walk, in the interoperability issue. One is if I want to call you and you want to call me, we should all know to use each other's memory systems. If I want to call one of your functions, I need to put something on your stack. I need to know your stack, and I need to know your decoding ware and I need to know your memory system, etc, etc, and you should know mine, which is quite difficult.

    But there is another way and this other way is called Mediator. If I know to speak to someone -- I don't know to speak to you -- but I know to speak to someone that you know to speak to. I can speak you him and he will speak to you.
    Ron: Oh that would be just like if we had a translator here, let's say, and you didn't speak English.
    Manu: Exactly!
    Ron: You'd speak Hebrew to the translator, I don't know how to speak Hebrew, but I can speak English to the translator and then he can tell me what you said.
    Manu: Exactly this is much more simpler. I don't need to learn English which is quite a task, I've worked on this from second grade. And this is much more simpler. Yes, there's a price here, you have to pay this translator, you have to bring him, you have to give him food and it takes longer of course, but it is much simpler and sometimes I'm willing to pay the price for simplicity.

    Lets say if we had a database and I'm writing some data to the database. I know from whatever technology I'm using, to write into this database and you know to read from this database or write to this database. Vice versa. So here we have a mediator. And sometimes it's amazing, we see the two technologies are working well with each other, interoperating by writing to a file, to a log file, to a database.
    Ron: You know, it's always the simple things that seem to work, sometimes we get all caught up and we have to do this complicated thing and I always find that when I see people going on a very complicated path, sometimes it's good to just say - stop for a minute - and think, is there a simpler way to do this?
    Manu: And there is. You know what, they invented XML. XML, XML can be thought of as such a resource we can write to. Everybody knows how to speak XML.
    Ron: Yeah.
    Manu: This is why XML is so huge and so popular.
    Ron: Yeah.
    Manu: C++ knows how to read and write XML. Managed code knows how to read and write XML. Java code knows how to read and write XML.
    Ron: OK.
    Manu: And from XML, you have many, many standards than everybody else, like WS-Star standards. And you have many frameworks, in Java, in J2EE, in.NET, in C++; they all know how to read and write WS-Star. And they all know how to read and write XML, which is much simpler.
    Ron: OK. Yeah.
    Manu: Now, let's say I am C++ code and I want to call you. But I'm not really accessing your memory; what I'm doing is I'm writing some sort of XML and I'm sending this to you, through TCP, HTTP, MSMQ, or whatever. Now, you how know to create a socket. You know how to listen or write TCP, MSMQ, etc. You know how to communicate to the world, and these are standard communication systems. So if I write this XML to you and you know how to read this XML, this XML is really[?] my mediator.
    Ron: Yeah.
    Manu: And here, I don't know your memory. I don't know how you do the coding, etc. I'm just writing XML. And here, we are interoperating, which is amazing.
    Ron: Yeah. And so you're saying that WCF could be the mechanism that we use to sit between the C++ code and the C# code. It could be this mediator that allows us to send these XML messages between the two.
    Manu: Exactly. And not just C++, any technology.
    Ron: Oh, sure.
    Manu: Now, the thing is, the C++ was designed for this. If you speak to the people who designed WCF...
    Ron: Yeah.
    Manu: Excuse me. WCF was designed exactly for this. If you speak to the people who designed WCF, they will tell you that they have done a lot, a lot of work for interoperability, for future interoperability. They know the importance of interoperability, and this is amazing. What they've done, they've put a lot of work to make WCF simple--A, B, C--in behavior.
    Ron: Yeah. It makes a lot of sense. A lot of people don't realize that one of the key design goals for WCF was not only so that customers could use it, but that so Microsoft could use it as well, because we have a lot of components and products in the OS and server products that need to communicate together.

    And most of the communication in Windows is based very much on a really old technology of RPC, or a step up from that, DCOM, and as we're wanting to take the platform forward, we have to have something better to have these communications. And we don't want everybody writing random communication stuff; that would be way too hard to secure the platform. So WCF has to be very interoperable with C++ code, because a lot of Windows is going to remain C++ forever. [laughs]
    Manu: Of course.
    Ron: Right? So it seems like this is a great solution. Now, a lot of people will hear this and they'll say, "Well, of course you can send messages from C++ code on one machine to C# code running on another machine." Which is, at first, what I was thinking when you talked about that. And then I realized, "No, wait. No, we could be talking about two DLLs that live on the same machine that just want to communicate between each other, and we're going to use named pipes between them."

    The question is, a lot of people will say, "Well, wait a minute. The performance is going to be a problem. I've got to have really fast performance." A lot of people were worried about COM Interop. [laughs] And as you say, am I going to do this? Is that going to really hurt?
    Manu: Well, that's amazing because, again, WCF had done a lot, a lot of work to make this technology as performant as possible. And, well, tomorrow in the conference, I will show... I just compared the WCF against other distributing technologies, and you can see that WCF is far, far, far more efficient than others.
    Ron: Wow.
    Manu: Because of named pipes, and because of other mechanism that are working in WCF. They have done a lot, a lot of work to make it as efficient as possible. It is much more efficient than remoting. OK? Seven to 10 times more efficient. It's amazing.
    Ron: Oh, wow.
    Manu: We are talking scale. OK? Now, OK?
    Ron: Yeah.
    Manu: What I did in one of my projects with my customers, I measured how much time it would take me to interoperate, using, let's say, Platform Invoke, using COM Interop. And then I've gone to the simpler solution by sending a message, using TCP, net TCP, as efficient as possible. And I found out that there is a difference, but it is very, very small.
    Ron: Yeah.
    Manu: It is very, very small because WCF is so efficient itself. Now, I can say that, yes, this is message binding -- which is, "Oh! Message binding! Performance! How?"
    Ron: Yeah.
    Manu: "No way! We won't think about that." But what I'm saying is go and check.
    Ron: Yeah.
    Manu: Go and check. Message binding can be efficient. And XML is not another word for losing performance. XML can be efficient. If you decode XML binary, you will find out that sometimes it is even more efficient than remoting, which is encoded binary.
    Ron: Well, I remember the first time I saw WCF, which was way, way long before it was released, in--I think it was 2002--early 2002, when I saw it. When they were first running tests, the very first thing they worked on was the named pipes. So they didn't even work on the web service part of it, the HTTP bindings or anything, for much longer after that. So I'm really not too surprised that they got the named pipes really well.
    Manu: Oh, yeah.
    Ron: Because that was the part they worked on for the longest. Because of the fact that they were really thinking about this, primarily as platform infrastructure that had to good enough for parts of Windows to use eventually.
    Manu: We're using this. It's just amazing. We have to get out of the box a little bit.
    Ron: Yeah.
    Manu: And when I show this to customers, they say they don't want to hear this first. But then we have to get out of the box and just think, and we see amazing results. And the thing is that when we are writing code, we have to think about the future. We have to think about the things that we will change. And this code base should be as simple as possible, not because we want to have less bugs and we want it as small as possible, etc. We want other people to understand this tomorrow. We want this code to be maintainable.

    WCF is simple. Actually, you write a little bit of config, and your code is very, very, small, and that's it. You don't have to write huge memory management, etc, etc. So, this is just a very thin layer, and here you are. XML is simple. It can be simple.

    Sometimes when you say, "OK, I don't want security. I don't want transactions. I just want to pass data. That's it." So this is really simple. You find out that you went way, way, way too complex of a solution, when you could just write a very simple XML.

    When you want to security and transactions, etc, etc, and you want to use WS-Security, WS Atomic Transaction, etc. This XML is getting a little bit longer, and a little bit more complicated. But for that -- even for Win32, C++ code, and for Java, etc -- you have frameworks that write WSR protocols WSR XML. You don't have to write this parcel yourself.

    So even then, you can just send a message. It will be a little bit less simple, but you can do it.
    Ron: So, just to be clear, when we're saying using WCF as the mediator, we're speaking about, on the C# side, using WCF to create an endpoint, and listen at that endpoint to messages that are coming in. On the C++ side, to send the message we're not really using WCF, you're just opening a main pipe, shoving the XML down it in the appropriate format.

    Now, I want to be clear on that because some people will be like, "How am I going to use WCF on the C++ side if I don't load MS Core EE and all of that, right?" So, that's not what we're talking about. You could do it, but then you'd be back to some of the complicated stuff about loading the CLR into your process space.
    Manu: Of course. Of course. You are completely right.

    I had some customers, and they started to think about message based minding[?]. Then they got to the client. The client is WCF. We know to write WCF using managed code, so here again, we have the interpretability problem inside our little process, so you have to load the MS Core EE, etc, etc.

    So, how do we do this? It was amazing. I saw a complex jigsaw puzzle, which any technology that they could put... Just to fit the jigsaw puzzle, and that everything would fit. It was amazing. They had remoting, they COM interrupt. They had everything just to fit it in.

    And then I told them, "Look. WCF on the server side doesn't know who is the client. It doesn't care about the client. This is service oriented architecture." Service oriented architecture means that the service and the client are autonomous.

    Services should be autonomous. This is one of the most important tenants of SOA, Service Oriented Architecture, which means that I don't care who is my client. All I care is about the data that I get. If you create a C++ client that can send me the right XML, or even not the XML, it can be a stream of bytes.

    There is MSNQ Integration Binding. With MSNQ Integration Binding, you don't send in XML. You just send of bytes. You can. You can send a stream of bytes. Simply, a stream of bytes, and it is transported through MSNQ. The MSNQ likes wrapping. It's like the XML wrapping, but through MSNQ. And then, in WCF, I open the stream of bytes. All I care about is the data.

    So, if we understand the way that we are going to send data. It's like a little contract that we're having. And you're going to send me the right data, you don't have to be a WCF client at all.
    Ron: You know, that's kind of a mind shift from all of the previous distributed communication technologies. Whether it was RMI, or DCOM, or CORBA. They always operated on the assumption that the consumer and the receiver were both using the same thing. That you had to use this, or we're not talking, pretty much.
    Manu: Exactly. Exactly.
    Ron: But it's really simple when you think about it now that, "Hey, all you have to do is send me XML over this transport. I don't care what you're using." But, that's how we achieve interop at the Web Service Level with other platforms but, really, this is just another case of that.
    Manu: Exactly. I cannot assume what technology that you're using. I am a service and that's it. I cannot tell you, "OK, if you want to work with me, you have to work with.Net." Let's say that you were this and that company, somewhere in the world. I cannot be that rude.

    Ron: Well, actually, we don't to think of it that way, but I know what you mean. We can't throw those kind of requirements on. People have what they have, and they want it to work together, and so that's the brave new world we're in with WCF.
    Manu: Exactly.
    Ron: Excellent. Well, I have to admit, until today I have never thought of doing what you suggested but, for some people, I think it's going to be a very good solution to bringing that C++ code forward, and connecting it to newer code that they're writing, and manage C# or, and so it's very important information.

    Thank you so much for sharing with us.
    Manu: Thank you.
    Ron: Oh, wow. Can you imagine bringing the kind of recommendation to your boss like, "Hey boss, you know all that C++ code we've got? We're going to rip that all out and rewrite the whole thing in.Net." I mean, you just can't get away with that in many cases. And really, it's probably the smartest thing to do.

    I mean, a lot of that code is good code. It's working. It's been around for a long time. We've got to figure out how to move forward into new technologies in new ways, while still preserving the things that worked from the past. Manu had some great advice for us, a lot of interesting ideas. This is what makes ARCast so fun. I'm always learning new things, and I hope you are too. Thanks for watching ARCast TV.
    Announcer: ARCast TV is a production of the Microsoft Architecture Strategy Team,
  • User profile image
    For projects that don't use a whole lot of advanced c++ features and rely on pointer arithmetic for performance reasons, there's a new tool around called c++ to c# converter. It's still a "v1" product and though some manual modifications to the resulting code was necessary it took one day to convert ~1 megabyte of cpp/h files to .cs.

    Now dealing with the couple native libraries proved out to be the more challenging part as someone had already created wrappers for them but it turned out the wrappers didn't actually implement everything that was available in the native library.
  • User profile image

    I am trying to create a WCF Service which communicates to a C++ client through named pipes.  I have run into some problems and have a few questions. 

    1.       What are the benefits of using WCF over using PInvoke of the Named Pipes APIs?

    2.       How do you access a named pipe endpoint from a native C++ app that is created using WCF?

    3.       Is there a simple way to create a native C++ proxy from a WCF service?  Using the svcutil to generate the proxy in c++ create a c++/cli file.

    Any resources or sample code relating to implementing this idea would be greatly appreciated. 



Add Your 2 Cents