468,170 Members | 1,923 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,170 developers. It's quick & easy.

How to reach unmanaged API functions from managed code?

I've been instructed to work againt a huge unmanaged C++ API from a C#
application.

Now, the only way, as I've understood it, is to go the Managed Extensions
for C++ way. This means I have to write a wrapper between unmanaged API and
my managed app.

Now on to the question:

If there's an unmanaged API class called X with a defined method

TypeA* foobar(TypeB* b, TypeC* c);

then how can my managed code (my c# app) deal with the problem of inputing
TypeB and TypeC since they are not known or compatible with managed code,
and how should my c# app deal with the TypeA* return type?

Is there a way to "use" the unmanaged types "as they are" in the managed
code (maybe by uisng the API include files?) or do I have to do something
like this in my wrapper:

TypeA, TypeB and TypeC consists only of a public int member for simplicity.

public __gc class wrapper
{
public:
wrapper() {m_obj = new X;}
X* m_obj;
....

// exposed to the managed code to be able to
// talk to the API foobar method
int wrappedFoobar(int b, int c)
{
TypeB* bTmp = new TypeB(b);
TypeC* cTmp = new TypeC(c);

TypeA* aTmp = m_obj->foobar(bTmp, cTmp);
return aTmp->m_nInt;
}
}

This is EXTREMELY cumbersome if I want to use large parts of the API... or
not even doable if the types are really complex. Is there a way to reach
the unmanaged API where I'm not forced to practically rewrite the entire
library in managed code?

PLEASE, reply also to to***@grafu.se.

Sincerely,

/Tommy
Nov 17 '05 #1
3 1711
"Tommy Svensson (InfoGrafix)" <to***@infografix.nu> wrote in message
news:el****************@TK2MSFTNGP15.phx.gbl...
I've been instructed to work againt a huge unmanaged C++ API from a C#
application.

Now, the only way, as I've understood it, is to go the Managed Extensions
for C++ way. This means I have to write a wrapper between unmanaged API
and
my managed app.
Well, sometimes what developers do is to define a managed class in MC++
(soon to be C++/CLI) which exposes the same public interface. That done,
callers written in any CLS compliant language can create objects of the MC++
class.

Another option is to wrap up the C++ class into a COM object and then take
advanatge of the fact that .Net applications can consume COM objects.

A third option is to "flatten" the existing object oriented interface into a
procedural one which exposes its interface via exported DLL functions and
then use .Net's Platform/Invoke (aka P/Invoke) from .Net.
Now on to the question:

If there's an unmanaged API class called X with a defined method

TypeA* foobar(TypeB* b, TypeC* c);
then how can my managed code (my c# app) deal with the problem of inputing
TypeB and TypeC since they are not known or compatible with managed code,
and how should my c# app deal with the TypeA* return type?
Well, you can always treat the pointers as opaque cookies or handles on the
managed side of things. If you do that you will need to validate the
"handles" before you dereference them (or suffer the consequences <g>).
Depending on how complicated the types are you may be able to define
equivalent "structs" for C#.

IMO, the most elegant way, and the one that often involves the most work is
to define a .Net proxy class each of whose instances contain a pointer to an
instance of a ntaive object. The constructor of the proxy class would take
advantage of MC++'s "it just works" capbility to hop the fence into
unmanaged code and invoke the constructore for the managed object. Every
public method in the proxy class would then marshall its arguments, delegate
to the corresponding in the native object and unmarshall the result.

These articles address some basic interop issues from the perspective of teh
C# developer:

http://msdn.microsoft.com/library/de...rp09192002.asp

http://msdn.microsoft.com/library/de...asp?frame=true

http://msdn.microsoft.com/library/de...asp?frame=true

And the book "Essential Guide to Managed Extensions for C++" (APRESS
1-893115-28-3) written by Challa and Laksberg (of the VC++ team) does a good
job of explaining interop from the perspective of a C++ programmer.

Note that VS2005 is going to change the syntax of managed C++ in a major
way.
PLEASE, reply also to ...


Post it here, read it here.

Regards,
Will
Nov 17 '05 #2
> Well, sometimes what developers do is to define a managed class in MC++
(soon to be C++/CLI) which exposes the same public interface. That done,
callers written in any CLS compliant language can create objects of the MC++ class.

Yes, this is what I'm trying to do as it seems to be the fastest option.

Another option is to wrap up the C++ class into a COM object and then take
advanatge of the fact that .Net applications can consume COM objects.

No can do, the API is huge, more than 2 000 files and thousands of classes
and functions.

A third option is to "flatten" the existing object oriented interface into a procedural one which exposes its interface via exported DLL functions and
then use .Net's Platform/Invoke (aka P/Invoke) from .Net.

No, for the same reason as above.
If there's an unmanaged API class called X with a defined method

TypeA* foobar(TypeB* b, TypeC* c);
then how can my managed code (my c# app) deal with the problem of inputing TypeB and TypeC since they are not known or compatible with managed code, and how should my c# app deal with the TypeA* return type?

Well, you can always treat the pointers as opaque cookies or handles on the managed side of things. If you do that you will need to validate the
"handles" before you dereference them (or suffer the consequences <g>).
Depending on how complicated the types are you may be able to define
equivalent "structs" for C#.

Ok, so in the API I have a type called WString which is a unicode string
type only.

If I try to return a string of type WString from a MC++ class to managed
code like this

char* wrapper::returnString()
{
return m_apiObj->my_WString.c_str();
}

then how should I receive this string? Like this:

String str = wrapperObj.returnString();

Will this work? How will I know what unmanaged string are compatible with
..NETs single string type String?

IMO, the most elegant way, and the one that often involves the most work is to define a .Net proxy class each of whose instances contain a pointer to an instance of a ntaive object. The constructor of the proxy class would take
advantage of MC++'s "it just works" capbility to hop the fence into
unmanaged code and invoke the constructore for the managed object. Every
public method in the proxy class would then marshall its arguments, delegate to the corresponding in the native object and unmarshall the result.

Is there a list somewhere of what unmanaged types get unmarshalled to what
managed types?

These articles address some basic interop issues from the perspective of teh C# developer:


Thx!
Nov 17 '05 #3
"Tommy Svensson (InfoGrafix)" <to***@infografix.nu> wrote in message
news:u7**************@TK2MSFTNGP15.phx.gbl...
Ok, so in the API I have a type called WString which is a unicode string
type only.

If I try to return a string of type WString from a MC++ class to managed
code like this

char* wrapper::returnString()
{
return m_apiObj->my_WString.c_str();
}
Well, why do you want to a null terminated array of characters to your
managed proxy? That's done in the unmanaged world mostly because in the
beginning (K&R days) that's all there was. .Net has a string class, so it
seems more nature to invoke the constructor of System::String(). And if your
managed class is going to be used by, say C# clients or VB.Net clients, you
certainly don't want to be exposing character strings of null terminated
characters. Or do you?
Will this work? How will I know what unmanaged string are compatible with
.NETs single string type String?
Instances of System::String are composed of wide characters. Take a look at
its constructors and build one from your unmanaged array of characters.
Is there a list somewhere of what unmanaged types get unmarshalled to what
managed types?
I don't know. Perhaps someone else here has an idea.
Thx!


You are welcome.

Regards,
Will
Nov 17 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

4 posts views Thread by repstat | last post: by
2 posts views Thread by Brett Styles | last post: by
9 posts views Thread by Amit Dedhia | last post: by
2 posts views Thread by Jon Slaughter | last post: by
1 post views Thread by gcdp | last post: by
reply views Thread by kamranasdasdas | last post: by
reply views Thread by gcreed | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.