This class(wrote by me) show how you can call native functions of a library(dll/exe) without a DllImport wrap using delegates, basically every function exported in the library has an address to use as entry point(pointer), Marshal just deference the pointer with the delegate type.
Code:
    static class NativeLibMethods
    {
        [DllImport("kernel32.dll")]
        public static extern IntPtr LoadLibrary(string lpFileName);
        [DllImport("kernel32.dll")]
        public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
        [DllImport("kernel32.dll")]
        public static extern void FreeLibrary(IntPtr hModule);
        [DllImport("kernel32.dll")]
        public static extern void FreeLibraryAndExitThread(IntPtr hModule, uint dwExitCode);
    }

    class LibLoader
    {
        public string libName { get; private set; }
        public IntPtr libPtr { get; private set; }

        public static LibLoader LoadLib(string lib)
        {
            IntPtr plib = NativeLibMethods.LoadLibrary(lib);
            if (plib == IntPtr.Zero) 
                throw new EntryPointNotFoundException("Library "+lib+" not found");
            return new LibLoader(lib,plib);
        }

        private LibLoader(string name, IntPtr lib) 
        {
            this.libName = name;
            this.libPtr = lib;
        }

        public TDelegate GetFunc<TDelegate>(string name)
        {
            if (!typeof(TDelegate).IsSubclassOf(typeof(Delegate))) 
                throw new ArgumentException(typeof(TDelegate).Name + " is not a delegate");
            IntPtr func = GetEntryPoint(name);
            if (func == IntPtr.Zero) 
                throw new EntryPointNotFoundException("Function " + name + " not found in " + libName);
            return (TDelegate)(object)Marshal.GetDelegateForFunctionPointer(func, typeof(TDelegate));
        }

        public IntPtr GetEntryPoint(string name)
        {
            return NativeLibMethods.GetProcAddress(libPtr, name);
        }

        public void Free(bool exit = false, uint code = 0)
        {
            if (exit) 
                NativeLibMethods.FreeLibraryAndExitThread(libPtr, code);
            else 
                NativeLibMethods.FreeLibrary(libPtr);
        }

        public override string ToString()
        {
            return libName;
        }
    }
Example
Code:
private delegate void MessageDelegate(string message);

//etc...

var msglib = LibLoader.LoadLib(".\\YourDll.dll");
var ShowMsg = msglib.GetFunc<MessageDelegate>("ShowMessage");
ShowMsg("TEST LOL");

//etc...

msglib.Free();
ps: check out also http://www.dependencywalker.com/