views:

594

answers:

3

I am writing a Visual Studio add-in to process C++ code, and think that COM interop is slowing me down to much. I therefore want to pass a C# reference to a COM object to a small C++ DLL, have the DLL perform the necessary calculations and return back a string.

I would be passing a CodeFunction2 object to the DLL and getting an XML string with information on the method back.

While you are welcome to question whether I really need this for the performance boost, if you call a dozen member variables accross a COM interop for thousands of methods it seems to eat up way too much time changing between managed and unmanaged code.

How do I format the arguments to the C++ DLL? I have no experience with calling unmanaged code from managed code in general, but the main question I need answered is how to format the call.

+1  A: 

Maybe you should write a Managed C++ dll instead (using the /clr switch), then you can directly pass managed objects into the C++ dll and do whatever COM magic you like without worrying about passing them between dlls.

John Fisher
Is the back end different from .NET? Wouldn't this still have the COM interop problem? Am I confused or isn't this just changing the syntax of what I want to do. The issue is multiple accesses to COM fields of the CodeFunction2 object accross managed/unmanaged code is slowing everything down. How does managed C++ bypass this?
Managed C++ exists in both worlds simultaneously. You use "^" for pointers to managed objects, and "*" for pointers to typical C++ objects. One "managed" function can directly reference .NET objects, then go completely unmanaged for the next bunch of COM lines, then return to dealing with .NET objects. Mixing and matching is almost a no-brainer in managed C++.
John Fisher
You can directly access the COM pointers to the CodeFunction, which is good. Don't you still have to "switch context", for lack of a better term? How do you label a block of code as unmanaged? I want to prevent frequent context switches at the base level of my recursion.
You can do something extremely simply like writing a loop. Inside the loop, you use only standard C++ code. There will be no use of .NET object, so no context switching. Before and after the loop, you can reference .NET objects all you want. Again, mixing managed and unmanaged code in C++ is so easy, that it just happens accidentally while you're writing. If you don't explicitly reference a .NET object, it doesn't do any managed/unmanaged context switching. (In fact, there's not really any context switching at all. You have to explicitly code for conversions, or use the .NET functions.)
John Fisher
I'd give you another +1 if I could, but if I get this answered then you get the check: if I pass in the .NET pointer to the COM CodeModel2 object, does the managed C++ know to reference it from an unmanaged context? The pointer would still need to be passed in from a managed viewpoint, correct? How do I drill down in to the actual pointer to the native object?
You can pass the .NET object from C# to C++ just as you would if you were calling another C# dll. Inside the C++ function, you can write any code you like. The mixed mode of C++ doesn't care when or what you use. You can turn a managed object's data into unmanaged data once, then reuse that a billion times during calls to COM without touching managed code. You can get the COM pointer from the .NET object using functions from System.Runtime.InteropServices.Marshal. They'll give you IntPtr values that can be cast to native C++ COM pointers (since that's what they are).
John Fisher
Appreciate all of the help with this. Definitely answered my question
+1  A: 

If you honestly think the C# / COM interop is slowing you down, why not write your VS addin in C++? That would avoid having to pass from a C# addin dll into a C++ dll to handle the COM interop - do it all in the same place.

ScottTx
Not a bad idea, but there is a fair bit of GUI work. Frankly I mostly don't want to rewrite the thing, so I'm going to write the front end in C# and the backend in managed C++. But you're right, if I had it to do over, I'd probably just use managed C++ all the way. If you saying just use native C++ then the issue with that is I am using a lot of visual studio extensibility things and in VS 2008 that seems to work very well in managed code.
+1  A: 

As others have pointed out, Managed C++ would be a good idea, since it makes interop a jiffy. If you decide to use it, instead of Managed C++, I'd suggest C++/CLI, which is the same in features, but it's newer and has a much cleaner syntax (it is intended to replace Managed C++). (in Managed C++ you have thing like __gc and stuff which is ugly).

Here is a nice tutorial about interop scenarios.

Tamás Szelei
Good tutorial, thanks for the link