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

J

joye

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
 
I

Ian Griffiths [C# MVP]

joye said:
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?

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.
 
J

joye

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 said:
joye said:
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?

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top