Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / Interop / January 2005

Tip: Looking for answers? Try searching our database.

C# access to C DLL

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
_BNC - 10 Jan 2005 02:50 GMT
Here's the breakdown:

I have an old C DLL that I want to access via C#.

I'm doing this via an outer DLL that wraps the old C DLL in an unmanaged
C++ class, which is in turn wrapped in a Managed C++ class.  Both these
unmanaged C++ and managed C++ classes are compiled into a single assembly
(DLL) that is accessed by C#.

[C DLL]  <-->  [Unmanaged C++ / Managed C++]  <-->  [C# app]
 old dll          new C++ assembly                                    app

I don't want to use standard Interop methods.  I'm trying to do all the
direct access to the old C DLL with unmanaged C++.  The data types in the
old C DLL are relatively complex, so I'm encapsulating the cluttered
legacy stuff in the new unmanaged C++ class.

IOW, I'll usually only be passing ints and a couple strings between the
unmanaged and managed sides.

In general, this approach works, but I'm getting occasional runtime errors
that I can't explain.  Could someone post or refer me to a very simple
example that does this with even a single function?  Say, take a function
from a stock Windows DLL and show a correct unmanaged C++ class
and managed C++ class that will wrap it correctly.

Thanks for any insights you can provide.
_BNC - 10 Jan 2005 04:22 GMT
>Here's the breakdown:
>
[quoted text clipped - 9 lines]
>
>I don't want to use standard Interop methods.

Oops.  I meant I don't want to use PInvoke.  I'm using the flat 'IJW'
model.

> I'm trying to do all the
>direct access to the old C DLL with unmanaged C++.  The data types in the
[quoted text clipped - 11 lines]
>
>Thanks for any insights you can provide.
Nicholas Paldino [.NET/C# MVP] - 10 Jan 2005 15:14 GMT
_BNC,

   The example isn't going to be that complex, I am afraid.  Actually, you
don't even need code to show how to call the C code from the unmanaged C++
code.  The issue is properly handling the unmanaged C++ class (since it is
allocated on the unmanaged heap, etc, etc.).

   Because your class will have an unmanaged resource in it (the unmanaged
C++ class), you should implement the IDispose interface, so that the Dispose
method can be exposed, and the class can be cleaned up correctly.

   For more information on doing this sort of thing, check out the section
of the .NET framework titled "Managed Extensions for C++ Migration Guide",
located at (watch for line wrap):

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmex/html/vcgr
fmanagedwrappersaroundunmanagedtypes.asp


   Also, if you have time, and think that you can use the CLI extensions
(as managed extensions are going out the window), you might want to do that,
as it would be much easier, from what I hear.

   Hope this helps.

Signature

              - Nicholas Paldino [.NET/C# MVP]
              - mvp@spam.guard.caspershouse.com

>>Here's the breakdown:
>>
[quoted text clipped - 28 lines]
>>
>>Thanks for any insights you can provide.
_BNC - 10 Jan 2005 20:30 GMT
[re 'flat model / C++ interop' bridge to unmanaged DLL]

>    The example isn't going to be that complex, I am afraid.  Actually, you
>don't even need code to show how to call the C code from the unmanaged C++
>code.  The issue is properly handling the unmanaged C++ class (since it is
>allocated on the unmanaged heap, etc, etc.).

>    Because your class will have an unmanaged resource in it (the unmanaged
>C++ class), you should implement the IDispose interface, so that the Dispose
>method can be exposed, and the class can be cleaned up correctly.

I've done all unmanaged mem management (ahem) inside the unmanaged C++
wrapper.  I haven't used 'dispose', as I manually keep track of all the
alloc'd memory.  I don't think that's the problem, especially in that
there are only a couple large buffers that need to be accounted for.  I'll
give that another look, but the code problems occur before the dealloc of
any objects.

The problem IS that the bridge between unmanaged and managed is somewhat
of a black box to me.  I don't have time on this project to study the
Marshal class as thoroughly as I'd like, nor to review the sparse examples
that I've seen for 'flat model'.  I'm afraid I'm missing something.

Despite that, the only thing I'm passing between managed/unmanaged is a
few pointers, and the code that I was drawing from did not use Marshal for
transfering simple (int, short) types.

The other puzzling thing is that failures are intermittent.  It would seem
that (short of a sweep of the memory manager) they should either fail or
succeed.  The failure rate seems independent of machine speed or amount of
available ram.

With enough study time and clues, I'd be able to solve this easily, but
unfortunately, the project manager doesn't have much patience for a
methodical approach.

>    For more information on doing this sort of thing, check out the section
>of the .NET framework titled "Managed Extensions for C++ Migration Guide",
>located at (watch for line wrap):
>
>http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmex/html/vcgr
fmanagedwrappersaroundunmanagedtypes.asp

Thanks for the pointer.

>    Also, if you have time, and think that you can use the CLI extensions
>(as managed extensions are going out the window),

!?  Uh-oh.  I've done a search for CLI Extensions and come up with only a
handful of google hits.   Is this part of VS 2005, or is it something that
is currently accessible?

Thanks, Nicholas.

B
Nicholas Paldino [.NET/C# MVP] - 10 Jan 2005 20:46 GMT
_BNC,

   When I said that you would want to expose a Dispose method on the
managed end, it wasn't because of the memory management you use in the
unmanaged code, but for the class you use to wrap that code.  Simply, if
your class has all the operations exposed as methods, then you are going to
create and store an instance of that class in the managed wrapper.  You
should have a Dispose method on the managed wrapper so that it can dispose
of the unmanaged memory as soon as possible.

   Now it could be argued that if you delete the unmanaged memory properly
in the finalizer, then the CLR will handle the memory management.  However,
it isn't aware of the pressure that you place on the system to allocate that
class (or the buffers you manage), so it's probably better to expose an
IDisposable implementation.

   If you are creating instances of these classes (using auto pointers) and
using them only in your methods, and not storing them on the class level,
then the IDisposable implementation is not needed.

   As for CLI, check out the section of the Visual C++ Developers Center
titled "Translation Guide: Moving Your Programs from Managed Extensions for
C++ to C++/CLI", located at (watch for line wrap):

http://msdn.microsoft.com/visualc/whidbey/default.aspx?pull=/library/en-us/dnvs0
5/html/transguide.asp


Signature

              - Nicholas Paldino [.NET/C# MVP]
              - mvp@spam.guard.caspershouse.com

> [re 'flat model / C++ interop' bridge to unmanaged DLL]
>
[quoted text clipped - 54 lines]
>
> B
Willy Denoyette [MVP] - 10 Jan 2005 20:49 GMT
Can't help you if you don't show us some code (preferably a complete sample
that illustrates the problem) and/or more details about the run errors.
My guess is that you are passing un-pinned pointers to unmanaged code.

Willy.

> Here's the breakdown:
>
[quoted text clipped - 23 lines]
>
> Thanks for any insights you can provide.
_BNC - 11 Jan 2005 07:42 GMT
>> I'm doing this via an outer DLL that wraps the old C DLL in an unmanaged
>> C++ class, which is in turn wrapped in a Managed C++ class.  Both these
[quoted text clipped - 6 lines]
>> I don't want to use standard Interop methods.  I'm trying to do all the
>> direct access to the old C DLL with unmanaged C++.

>Can't help you if you don't show us some code (preferably a complete sample
>that illustrates the problem) and/or more details about the run errors.
>My guess is that you are passing un-pinned pointers to unmanaged code.

Yeah, I was hoping that there was a simple code illustration somewhere.
I've seen many examples for PInvoke, but very little info on wrapping
unmanaged code, especially with both unmanaged and managed C++
classes in the same module.  (Are there no code samples that do this?
I would have thought it was a common thing to do)

I will try to work up a simple example to post, but it will probably work
OK.  The actual app is complex, and apparently only turns up problems
when stressed.

Still, your comment about pinning pointers may well be the main problem.

I've bought plenty of books on the subject (Grimes, Troelsen, etc) but as
I mentioned, my client won't afford the necessary time to dig into it (I
bet no one has heard that before).  I believe it will take more more time
to NOT dig into the internals of this, but I don't have the luxury.   I do
have a feeling that my initial reference example may have taken some
shortcuts.

Re pinning, a couple Q's come to mind:

 Wouldn't pointer corruption only occur when the GC runs?  Otherwise,
 I can't imagine why a managed pointer would be altered.

 How often does the garbage collector normally run on a medium-sized app?
 (Presuming that lots of RAM is available)

 Any recommended references that address this directly?

_B

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.