We have an application written in good old plain unmanaged C++.
I need to add some functionality to the application. From the app's point of view, it will be just a function (or, perhaps, a COM object) that will accept arguments, do a lot of things internally and return a result -- a black box approach.
I'd like to write it in C#.
What would be the best way of interfacing between the C++ application and the C# code?
If this is a FAQ, could you please point me to a tutorial?
Thank you.
Best wishes,
Alex.
--
Address email to user "response" at domain "alexoren" with suffix "com"
Is there any other way to write an application? :-)
> I need to add some functionality to the application. From the
> app's point of view, it will be just a function (or, perhaps, a
> COM object) that will accept arguments, do a lot of things
> internally and return a result -- a black box approach.
>
> I'd like to write it in C#.
> What would be the best way of interfacing between the C++
> application and the C# code?
I hesitate to use words like best because the best approach often depends
alot on the _exact_ details of your task.
For the purposes of this reply I am going to _assume_ that it is OK to
fashion your solution in C# and expose it as a COM object to unmanaged
callers.
There are other ways to go. If you want another suggestion just ask.
IAC, with VS.Net 2003 I created this toy class in C#
using System;
using System.Runtime.InteropServices;
namespace ClassLibrary1
{
[ClassInterface(ClassInterfaceType.AutoDual)]
public class Class1
{
public Class1()
{
}
public void SayHello()
{
Console.WriteLine("C# says hello!");
}
}
}
Then I registered the assembly and created a type library from it with the
command:
regasm /tlb:ClassLibrary1Lib.tlb ClassLibrary1.dll
With VC++ 6.0 I created this toy application which uses the compiler's
type library import facility to read the type library and create a COM
wrapper to be used by unmanaged callers:
#include <windows.h>
#import "mscorlib.tlb" raw_interfaces_only
using namespace mscorlib;
#import "ClassLibrary1Lib.tlb"
using namespace ClassLibrary1;
int main()
{
CoInitialize(0);
_Class1Ptr class1(__uuidof(Class1));
class1->SayHello();
CoUninitialize();
return 0;
}
I put the C# assembly in the same directory as the executable and ran it. C#
speaks.
Regards,
Will
csc /t:module ..\src\csclib.cs
cl /c /clr /Fomancfun.obj ..\src\mancfun.cpp
cl /c ..\src\cfuncs.c
lib /out:cfuncs.lib cfuncs.obj mancfun.obj
In my case there was another stage, a C program calling the C++ program, you
would have cfuncs.cpp instead of .c.
Thanks for your reply.
"William DePalo [MVP VC++]" <willd....@mvps.org> wrote in message news:eWYB6$2TFHA...@TK2MSFTNGP10.phx.gbl...
> "Alex" <inss...@online.nospam> wrote in message
> news:O7ittc2T...@TK2MSFTNGP09.phx.gbl...
> For the purposes of this reply I am going to _assume_ that it is OK to
> fashion your solution in C# and expose it as a COM object to unmanaged
> callers.
That is correct.
> There are other ways to go. If you want another suggestion just ask.
Sure, why not, we're here to learn...
> [ClassInterface(ClassInterfaceType.AutoDual)]
That's all there is to it?
Neat.
> #import "mscorlib.tlb" raw_interfaces_only
Is the "raw_interfaces_only" significant?
Comments in line.
Best regards,
Peter Huang
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
--------------------
>From: "Alex" <inss...@online.nospam>
>References: <O7ittc2T...@TK2MSFTNGP09.phx.gbl>
<eWYB6$2TFHA...@TK2MSFTNGP10.phx.gbl>
>Subject: Re: How to call managed C# code from an unmanaged C++ application?
>Date: Tue, 3 May 2005 15:38:03 -0400
>Lines: 29
>MIME-Version: 1.0
>Content-Type: text/plain;
> charset="Windows-1252"
>Content-Transfer-Encoding: quoted-printable
>X-Priority: 3
>X-MSMail-Priority: Normal
>X-Newsreader: Microsoft Outlook Express 6.00.2800.1478
>X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1478
>Message-ID: <OHtZheBU...@TK2MSFTNGP09.phx.gbl>
>Newsgroups: microsoft.public.dotnet.framework.interop
>NNTP-Posting-Host: firebox.markham.insystems.com 216.191.154.61
>Path: TK2MSFTNGXA01.phx.gbl!TK2MSFTNGP08.phx.gbl!TK2MSFTNGP09.phx.gbl
>Xref: TK2MSFTNGXA01.phx.gbl microsoft.public.dotnet.framework.interop:7597
>X-Tomcat-NG: microsoft.public.dotnet.framework.interop
>
>Hello Will,
>Thanks for your reply.
>"William DePalo [MVP VC++]" <willd....@mvps.org> wrote in message
news:eWYB6$2TFHA...@TK2MSFTNGP10.phx.gbl...
>> "Alex" <inss...@online.nospam> wrote in message
>> news:O7ittc2T...@TK2MSFTNGP09.phx.gbl...
>> For the purposes of this reply I am going to _assume_ that it is OK to >
fashion your solution in C# and expose it as a COM object to unmanaged >
callers.
>That is correct.
>> There are other ways to go. If you want another suggestion just ask.
>Sure, why not, we're here to learn...
Since the managed code must be run in CLR runtime, we can host the CLR
ourselves which very complex and complicated. And I think it is not
necessary in this scenario.
http://msdn.microsoft.com/msdnmag/issues/01/03/clr/default.aspx
>> [ClassInterface(ClassInterface茅ype.AutoDual)]
>That's all there is to it?
>Neat.
The AutoDual tell the compiler to generated the both IDispatch and VTable.
For detailed information, please refer to ClassInterfaceAttribute Class in
MSDN.
>> #import "mscorlib.tlb" raw_interfaces_only
>Is the "raw_interfaces_only" significant?
>
raw_interfaces_only attribute
The raw_interfaces_only attribute suppresses the generation of
error-handling wrapper functions and __declspec(property) declarations that
use those wrapper functions.
The raw_interfaces_only attribute also causes the default prefix used in
naming the non-property functions to be removed. Normally, the prefix is
raw_. If this attribute is specified, the function names are directly from
the type library.
This attribute allows you to expose only the low-level contents of the type
library.
For detailed information please refer to The #import Directive.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/HT
ML/_predir_the_.23.import_directive.asp
Regards,
Yuri
"Alex" <inss...@online.nospam> ???????/???????? ? ???????? ?????????:
news:O7ittc2T...@TK2MSFTNGP09.phx.gbl...
You are welcome.
>> There are other ways to go. If you want another suggestion just ask.
>
> Sure, why not, we're here to learn...
As Peter has already pointed out, it is posssible to host the CLR from
within your application. To do that you start by calling
CorBindToRuntimeEx(). That will get a pointer to the ICorRuntimeHost
interface. You can use that to get an interface pointer to the default
domain. That done you can load assemblies, after which you can create
instances of classes in those assemblies and then call methods on those
instances, etc.
It is a lot of work and not normally necessary. I have a server application
which I allow clients to extend with applications in their favorite
developemnt environments - C++, .Net, Java, Delphi, Perl, Python etc. For
me, it just seemed like the right choice.
>> [ClassInterface(ClassInterface茅ype.AutoDual)]
>
>That's all there is to it?
Yup.
> Neat.
Very.
> #import "mscorlib.tlb" raw_interfaces_only
Not really, except that it was enough for me in whatever application from
which I cut and pasted the code. You should check the docs on the #import
facility of the MS C++ compiler.
Regards,
Will