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]