Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 1106541
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 17, 20262026-05-17T01:48:32+00:00 2026-05-17T01:48:32+00:00

I’m writing a C# library to wrap a Win32 API (the waveOut… family of

  • 0

I’m writing a C# library to wrap a Win32 API (the waveOut... family of functions), and have reached a point where I’m unsure how to manage the interaction between different parts of my code without breaking encapsulation. So far, I have a setup like this:

public class AudioDevice
{
    ...
    private WaveOutSafeHandle hWaveOut;
    ...
}

// All native method calls happen in wrapper methods here, providing
// uniformity of access, exceptions on error MMRESULTs, etc.
static class NativeWrappers
{
    ...
    internal static WaveOutSafeHandle OpenDevice(...) { ... waveOutOpen(...) ... }
    ...
}

// Native methods live in a class of their own, and are only called
// from NativeWrappers
static class NativeMethods
{
    ...
    internal static extern MMResult waveOutOpen(...);
    ...
}

The most important point in this code is that the handle wrapped by a Device is not visible to anything outside a Device.

Now I want to add an AudioBlock class, which will wrap the native WAVEHDR structure and the audio sample data. The problem I’m encountering is that from here on out, pretty much every other native function I’m interested in (waveOut[Un]PrepareHeader, waveOutWrite) needs both a handle and a WAVEHDR. It seems that either a device will have to touch a WAVEHDR, or a block will have to have access to a handle. Either approach means that some class interacts with something it conceptually has no business knowing about.

There are, of course, several ways to get around this:

  1. Make handles and/or WAVEHDRs internal rather than private.

  2. Make AudioBlock a nested class of Device.

  3. Have a third class (I hesitate to even think the name (foo)Manager) which maintains (for example) a mapping from blocks to headers, which, given a block, a device can use to help it play samples without touching the block’s internals.

There may be others; I’m hoping so 🙂

My objections (right or wrong) to these approaches:

  1. They might not be public in the strictest sense of the word, but using internal members seems like a copout to me. What are effectively implementation details are still visible to parts of the library which don’t need them. I keep thinking “what interface do I want to present to anyone either using or modifying this code?”

  2. This almost works in my head. By regarding a block as an “implementation detail” of a device, it seems more acceptable to allow it to rely on a device’s internals. Except that a block really is an independent entity; it’s not tied to a single device and isn’t used to help implement a device’s logic.

  3. This gets the closest to the level of separation I want to maintain, but is starting to stray into overengineering territory, as I so often do 😛 It also introduces the artificial idea that blocks have to be centrally allocated from somewhere to keep the mapping intact.

So, does anyone have any recommendations for (re)structuring this code? Valid answers include “Your objection #X is a steaming crock,” as long as you can persuade me 🙂 ETA: For example, if you think trying to enforce this kind of thing is better done by social means (documentation, conventions) than technical ones (access modifiers, assembly boundaries), please let me know and point me to some references.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-17T01:48:32+00:00Added an answer on May 17, 2026 at 1:48 am

    They might not be public in the strictest sense of the word, but using internal members seems like a copout to me.

    Personally, I’d just make the wrappers internal, and treat your whole set of classes as a single public API.

    I understand the desire to avoid this – it forces you to create classes, which, for you during your development, violate the single responsibility principles.

    However, from the POV of the “outside” world, anybody using your software will see each class you provide having a single, clear responsibility, and a single purpose. The API can be at least as clean as the ones you’re wrapping (probably much simpler, given the managed code).

    My main motivation for doing this, in this situation, is one of practicality. Yes, I agree with the guidelines you’re trying to follow here – but, they’re guidelines, and guidelines are something worth following provided they don’t cause more harm than good. I commend you for trying to keep this as clean and elegant as possible, but unfortunately, it sounds like, in this situation, trying to make this “more elegant” is going to lead to more code, which will equate to less maintainable.

    I’d stick with the shortest, simplest solution here – making the native wrappers internal, so you can get to the data structures you need in your wrapper classes. Just document what you’re doing, and why.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a string like this: La Torre Eiffel paragonata all’Everest What PHP function
I have a .ini file as follows: [playlist] numberofentries=2 File1=http://87.230.82.17:80 Title1=(#1 - 365/1400) Example
link Im having trouble converting the html entites into html characters, (&# 8217;) i
I have just tried to save a simple *.rtf file with some websites and
this is what i have right now Drawing an RSS feed into the php,
I have a small JavaScript validation script that validates inputs based on Regex. I
I have this code to decode numeric html entities to the UTF8 equivalent character.
I have a French site that I want to parse, but am running into
I'm parsing an RSS feed that has an ’ in it. SimpleXML turns this
I have this code: - (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock { NSString *someString = [[NSString

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.