I am working to create a C# library that wraps a C DLL to integrate with our test system. The C DLL has probably close to 100 functions that can be accessed and all from the same DLL. I don't need all functions wrapped at this time, but I want to ensure I am setup in a direction that makes implementing everything maintainable.

The DLL 'groups' many of its functions under different purposes to help create separation. My plan was to create a class that is the main access point that contains generic functions and then create separate classes that create extension methods for the generic class.

Lets say my 'groups' are:

  • Generic
  • Acquisition
  • Selection
  • Interaction
  • Utilities

I would then create my main class

public class BaseClass
    // Generic methods

Then the other groups would each be their own static extension class:

public static class AcquisitionClassExtensions
    public static int AcquisitionMethod1(this BaseClass b)
        // Access DLL

And continue for the other groups. This would let me keep the BaseClass as the main object class that the DLL would be interacted with.

The user would still see a huge list of methods when viewing intellisense, but from a project maintainability I can keep things separate. I am sure i would run in to problems if one of the extension methods ends of needing some sort of state tracked, but that is minimal.

Is there a better way i could approach this or am i worrying about nothing?

Clarity Edit:

The generic group or BaseClass contains the basic connection access to the hardware system that the DLL is for, and that would maintain state. The other groups are special operations that can be performed on the hardware. The goal being if a new set of functionality is added it can be added with the extension methods like the other groupings.

  • Not sure I can effectively answer this, but could you clarify some points for me about how you plan to organize it? From what I understand, you have this rather large all-in-one DLL. Then for this BaseClass -- I couldn't fully understand what was meant by Generic methods in this context (generic part confused me a bit), but it seems like BaseClass is the sole one accessing the DLL (and therefore quite monolithic). Then you organize access to this rather monolithic BaseClass through various classes with static methods? Is that correct?
    – user204677
    Commented Dec 18, 2015 at 8:18
  • 1
    Let me clarify that generic part. The entire Dll provides access to a rather involved hardware system. The generic or Baseclass would contain the methods that allow you to connect to the hardware and get state of the system. The other groups are all different actions you can perform. Acquire signals, and make updates. The C# side would have many extension methods that are just the implementations of the functions from the DLL, then if a new set of functionality is added it would just be another extension class. Does that clear it up at all for you? Commented Dec 18, 2015 at 13:04
  • Yes, very much -- thanks! It might be great if you could add that to your question to clarify what's meant by this generic base class, assuming I'm not the only one who wasn't sure what that meant.
    – user204677
    Commented Dec 18, 2015 at 13:05

1 Answer 1


I suppose that when you are speaking of adding extension methods, you are thinking of enriching the functionality of the C library. I would advise against that, because a collection of 100 methods is not an object-oriented interface, and as such it will most probably not be amenable to extension.

Now, the concept of object-oriented programming is not unknown to C programmers; in fact, many, if not most, systems written in C do have some concept of objects, they just do it in their own way which might not be readily recognizable. For example:

  • <stdio.h> files are, in a sense, an object-oriented construct. The object in this case is a struct called FILE.

  • <fcntl.h> files are, in a sense, an object-oriented construct. The object in this case is hidden behind an int handle.

  • In the Windows API there is a multitude of objects, also hidden behind various different types of handles, the most famous of which is HWND.

I do not know whether the C library that you are using has any kind of object-oriented notion like the above, but many chances are that it does. If it does not, then I guess there is nothing special you can do, proceed the way you were planning. But if it does, then the design pattern that you probably need here is The Wrapper.

So, what you should do, if possible, is detect what object-oriented entities are utilized by your library, and introduce a C# class for each one of them. If you were creating a wrapper for <fcntl.h>, you would be creating a class File which contains a single member, private readonly int handle and offers a bunch of methods that delegate to the native functions like read(), write(), etc. passing them the int handle contained within the object.

Then, you would enrich those classes with additional functionality, (either by inheritance or by composition,) instead of extending the native-interfacing class. The best thing to do with the native-interfacing class is to keep it as short as possible, and hidden. ("internal" to the assembly that contains it.)

For more information, see:

  • There is some level of object orientation. The DLL connects to a hardware system which has subsystems, and those subsystems have unique signals that be accessed. The extension methods in this case are not for enriching the API to the DLL but for creating the access to it. I want to have a more C# looking wrapper that calls those externed methods. Now my plan is once i have this wrapping complete, I would then create class for say HardwareSubsystem that would contain only the necessary methods that a hardware subsystem would need. That would be used. Commented Dec 18, 2015 at 14:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.