An MP3 stream contains info for generating a set of samples where each sample corresponds to a sample in the original LPCM data (like from the WAV file), but a side-effect of encoding is that there is some extra "junk" added to each end, and a side-effect of decoding is that there is even more junk added to the beginning. The decoder will know how much it adds and will skip those samples, but the encoder-added junk isn't entirely predictable (different encoders add different amounts), so the decoder can't skip those samples unless it is somehow informed of what to skip. Some encoders, like LAME, will add such "gapless playback" or "delay and padding" info (in an encoder-specific format, because there's no standard for it) into the file's VBR Info (VBRI) or Xing header, which is sort-of standard even on CBR files, and which contains other info that is sometimes helpful to the player. This header is actually a frame of silence (usually 1152 samples) with some specially formatted info embedded in between the frame's header and the start of its null audio data. Most decoders/players recognize the frame as special and skip those samples, but some don't, so there's another potential point of failure. so I would look toward making sure you use a compatible encoder/decoder combo to get correct-length, junk-trimmed files as output.
Your second question...did you notice the LAME command-line app's "--decode" option? :) This should solve your problem if you're using LAME as the encoder. The output length should match the input.