Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to call managed C# code from an unmanaged C++ application?

31 views
Skip to first unread message

Alex

unread,
May 2, 2005, 6:34:57 PM5/2/05
to
Hello,

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"

William DePalo [MVP VC++]

unread,
May 2, 2005, 7:37:58 PM5/2/05
to
"Alex" <inss...@online.nospam> wrote in message
news:O7ittc2T...@TK2MSFTNGP09.phx.gbl...

> We have an application written in good old
> plain unmanaged C++.

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(ClassInterface­Type.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


Richard MSL

unread,
May 2, 2005, 9:31:02 PM5/2/05
to
I did this with an intermediate stage: a managed C++ function. My unmanaged
C++ function called a managed C++ function, linked into the same executable.
The MC++ function used the magic of .NET to call the C# which resided in a
separate .netmodule file which must be present at run time. Here is the batch
file to build it:

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.

Alex

unread,
May 3, 2005, 3:38:03 PM5/3/05
to
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...

> [ClassInterface(ClassInterface­Type.AutoDual)]

That's all there is to it?
Neat.

> #import "mscorlib.tlb" raw_interfaces_only

Is the "raw_interfaces_only" significant?

Peter Huang [MSFT]

unread,
May 4, 2005, 11:11:18 PM5/4/05
to
Hi

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

Yuri O at

unread,
May 7, 2005, 3:35:21 AM5/7/05
to
Hi
I do noy need COM as you directly connect your unmanaged code to managed
one
see:
ms-help://MS.MSDNQTR.2003APR.1033/vcmxspec/html/vcManagedExtensionsSpec_16_3
.htm

Regards,
Yuri

"Alex" <inss...@online.nospam> ???????/???????? ? ???????? ?????????:
news:O7ittc2T...@TK2MSFTNGP09.phx.gbl...

William DePalo [MVP VC++]

unread,
May 7, 2005, 9:55:10 PM5/7/05
to
"Alex" <inss...@online.nospam> wrote in message
news:OHtZheBU...@TK2MSFTNGP09.phx.gbl...
> Thanks for your reply.

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


0 new messages