Connecting Tech Pros Worldwide Forums | Help | Site Map

How to use C# to call the existing libraries containing unmanaged C++ classes directly?

joye
Guest
 
Posts: n/a
#1: Nov 17 '05
Hello,

My question is how to use C# to call the existing libraries containing
unmanaged C++ classes directly, but not use C# or managed C++ wrappers
unmanaged C++ classes?
Does anyone know how to do that?

Thanks.
Tsung-Yu


Ian Griffiths [C# MVP]
Guest
 
Posts: n/a
#2: Nov 17 '05

re: How to use C# to call the existing libraries containing unmanaged C++ classes directly?


"joye" wrote:[color=blue]
>
> My question is how to use C# to call the existing libraries containing
> unmanaged C++ classes directly, but not use C# or managed C++
> wrappers unmanaged C++ classes?[/color]

Are the classes in ".LIB" files or ".DLL" files?

If they are in .LIB files, then there is no way of consuming these directly
from C#. The only .NET language that is able to consume unmanaged code
contained in a .LIB file directly is C++. The reason for this is that .LIB
files work by linking some or all of their contents into the output binary.
Any program that does this will therefore have unmanaged binary code in its
output. C# doesn't support this - the C# compiler always produces pure
managed code.

So if you need to use something in a .LIB, you're going to have to use C++.
The usual approach is to write a managed C++ wrapper. There is no way
around this. (I suppose you could technically write your own C# compiler
which supported hybrid managed/unmanaged output like the managed C++
compiler does. But that would be a deeply non-trivial undertaking. I'm not
aware of any such compiler already existing.)

If it's in a DLL, then just use the 'P/Invoke' technology. This means using
the [DllImport] attribute. Search for that in the help and on the internet
and you'll find loads of information. In particular, look at
http://www.pinvoke.net/

You say the libraries you want to use contain 'classes'. Does this mean you
want to use those C++ classes in the same way you use .NET classes in C#?
If so, that won't be an option. The C++ object model has some substantial
differences from the .NET model, so you cannot consume a classic unmanaged
C++ class from C#. (Managed C++ gets around this problem by supporting two
kinds of classes: managed and unmanaged. C# does not offer such a feature -
it only supports managed classes.) P/Invoke is designed to consume normal
procedural DLL exports, but not C++ classes. (DLLs were never designed to
expose classes in the first place. The C++ compiler's ability to export
classes across DLL boundaries is a bit of an afterthought.)

If you really do need to use classes rather than normal DLL functions, and
the classes have been exposed in a DLL, there is one way you might be able
to consume them directly in C#. You can call the class's entry points using
[DllImport]. But it's very painful - it won't feel at all like object
oriented programming. You will be required to communicate with the DLL at
the raw procedure call level, i.e. you'll be digging around beneath the
object model.

In short, it will become extremely obvious that DLLs weren't designed to
export classes, and you'll be confronted with the somewhat ugly workarounds
the C++ compiler uses.

And some things will be so difficult that it's probably simplest not to
attempt them: e.g., invoking virtual functions defined by the C++ classes.
The C++ compiler uses its own runtime mechanisms to do this that are not
directly supported in C#. You would need to handle vptr tables directly.
To be honest I don't even know if it's possible in C#. If it is, it'll be
messy. It'll be very much more effort than writing a simple managed C++
wrapper.

There's only one .NET language I'm aware of which attempts to consume
unmanaged C++ classes: managed C++.

The interop services available in C# are designed to consume COM objects,
and procedural entry points into DLLs. They are not designed to consume
unmanaged C++ classes.

--
Ian Griffiths - http://www.interact-sw.co.uk/iangblog/


joye
Guest
 
Posts: n/a
#3: Nov 17 '05

re: How to use C# to call the existing libraries containing unmanaged C++ classes directly?


Hello Ian Griffiths,

Thank for your kind of answering my question-consuming a classic unmanaged
C++ class from C#. Your answer is very clear and detail.
So, I agree that calling a classic unmanaged c++ class from C# is a hard
work.

The simular problem appear when I explicit link a c++ class DLL from C++,
and I need to wrapper
the method of class with C function and then call GetProcAddress() to use
the C function.
But, using implicit link c++ class DLL, I can use the methods of class
comfortablely.
Why VisualStudio(even VS.NET) didn't support the function such as
GetClassAddress() for developer,
so that we can use explicit link to manpulate a C++ Class?

Best Regards,
Tsung-Yu, Liu

"Ian Griffiths [C# MVP]" <ian-interact-sw@nospam.nospam> ¼¶¼g©ó¶l¥ó·s»D
:u1sM0#EXFHA.3540@TK2MSFTNGP15.phx.gbl...[color=blue]
> "joye" wrote:[color=green]
> >
> > My question is how to use C# to call the existing libraries containing
> > unmanaged C++ classes directly, but not use C# or managed C++
> > wrappers unmanaged C++ classes?[/color]
>
> Are the classes in ".LIB" files or ".DLL" files?
>
> If they are in .LIB files, then there is no way of consuming these[/color]
directly[color=blue]
> from C#. The only .NET language that is able to consume unmanaged code
> contained in a .LIB file directly is C++. The reason for this is that[/color]
..LIB[color=blue]
> files work by linking some or all of their contents into the output[/color]
binary.[color=blue]
> Any program that does this will therefore have unmanaged binary code in[/color]
its[color=blue]
> output. C# doesn't support this - the C# compiler always produces pure
> managed code.
>
> So if you need to use something in a .LIB, you're going to have to use[/color]
C++.[color=blue]
> The usual approach is to write a managed C++ wrapper. There is no way
> around this. (I suppose you could technically write your own C# compiler
> which supported hybrid managed/unmanaged output like the managed C++
> compiler does. But that would be a deeply non-trivial undertaking. I'm[/color]
not[color=blue]
> aware of any such compiler already existing.)
>
> If it's in a DLL, then just use the 'P/Invoke' technology. This means[/color]
using[color=blue]
> the [DllImport] attribute. Search for that in the help and on the[/color]
internet[color=blue]
> and you'll find loads of information. In particular, look at
> http://www.pinvoke.net/
>
> You say the libraries you want to use contain 'classes'. Does this mean[/color]
you[color=blue]
> want to use those C++ classes in the same way you use .NET classes in C#?
> If so, that won't be an option. The C++ object model has some substantial
> differences from the .NET model, so you cannot consume a classic unmanaged
> C++ class from C#. (Managed C++ gets around this problem by supporting[/color]
two[color=blue]
> kinds of classes: managed and unmanaged. C# does not offer such a[/color]
feature -[color=blue]
> it only supports managed classes.) P/Invoke is designed to consume normal
> procedural DLL exports, but not C++ classes. (DLLs were never designed to
> expose classes in the first place. The C++ compiler's ability to export
> classes across DLL boundaries is a bit of an afterthought.)
>
> If you really do need to use classes rather than normal DLL functions, and
> the classes have been exposed in a DLL, there is one way you might be able
> to consume them directly in C#. You can call the class's entry points[/color]
using[color=blue]
> [DllImport]. But it's very painful - it won't feel at all like object
> oriented programming. You will be required to communicate with the DLL at
> the raw procedure call level, i.e. you'll be digging around beneath the
> object model.
>
> In short, it will become extremely obvious that DLLs weren't designed to
> export classes, and you'll be confronted with the somewhat ugly[/color]
workarounds[color=blue]
> the C++ compiler uses.
>
> And some things will be so difficult that it's probably simplest not to
> attempt them: e.g., invoking virtual functions defined by the C++ classes.
> The C++ compiler uses its own runtime mechanisms to do this that are not
> directly supported in C#. You would need to handle vptr tables directly.
> To be honest I don't even know if it's possible in C#. If it is, it'll be
> messy. It'll be very much more effort than writing a simple managed C++
> wrapper.
>
> There's only one .NET language I'm aware of which attempts to consume
> unmanaged C++ classes: managed C++.
>
> The interop services available in C# are designed to consume COM objects,
> and procedural entry points into DLLs. They are not designed to consume
> unmanaged C++ classes.
>
> --
> Ian Griffiths - http://www.interact-sw.co.uk/iangblog/
>
>[/color]


Closed Thread