The error is occurring when the framework calls LoadLibrary. That can be deduced from the error message:
Unable to load DLL 'Foo.dll'
The error code that is reported is a COM error code that wraps Win32 error code 998, aka ERROR_NOACCESS. The scenario that leads to a call to LoadLibrary throwing ERROR_NOACCESS is described here: http://support.microsoft.com/kb/196069
SYMPTOMS
The LoadLibrary() API may sometimes encounter an access violation
  while attempting to map a specified module into the address space of
  the calling process. In this event, LoadLibrary() returns a value of
  NULL and GetLastError() returns an error code of 998 (ERROR_NOACCESS).
  Back to the top | Give Feedback
CAUSE
The Windows NT status code STATUS_ACCESS_VIOLATION is mapped to the
  Win32 error code ERROR_NOACCESS. As a result, if the operating system
  loader encounters an access violation (exception C0000005) while
  mapping the specified DLL file image or executing the startup code,
  the loader will set the last error to 998 (ERROR_NOACCESS) and the
  LoadLibrary() function will fail with a return value of NULL. Back to
  the top | Give Feedback
MORE INFORMATION
When an access violation occurs anywhere in the startup code, the
  exception dispatcher detects whether the process that encountered this
  exception is being debugged. If so, this first chance exception is
  sent to the debugger. 
To troubleshoot the LoadLibrary() failure, run the application under a
  debugger and enable first chance exception handling for the C0000005
  Access Violation exception. If an access violation occurs when the
  LoadLibrary() function is called, the application will break into the
  debugger. The debugger's call stack can then be used to trace where
  the exception occurred. The stack trace should help you narrow down
  the actual problem related to the exception being encountered. 
For information on how to enable first chance exception handling for
  the C0000005 Access violation exception, please refer to the debugger
  documentation.
In essence, your DLL is producing an access violation in its startup code. Many things could cause that and you'll need to do some debugging of the DLL. I suggest that you attempt to debug this from a native C++ host. It will likely be easier to debug the DLL that way.
As an aside, your function uses the cdecl calling convention, and once you get past the current hurdle, you'll need to modify your C# p/invoke to specify CallingConvention.Cdecl.