DLLs are libraries with named functions in them. Usually the names are human readable. C++ has this thing in it call named mangling. This is to allow for overloaded functions and other things. When you build a C++ DLL, all the functions will be exported as their mangled names. Every compiler mangles differently. This isn't a problem if you use the LIB file, because the compiler will automatically link to the correct mangled name in the DLL. This requires that you be statically linked to the DLL, and that it be compiled with the same compiler. If you want to load DLLs at runtime using LoadLibrary, you will need to know the mangled name for use with GetProcAddress. So all this gets complicated really fast.
There is a simple way around this using a factory method. Take for example DirectX. You call Direct3DCreate9 to get pointer to a IDirect3D9 object. Instead of calling "new Direct3D9()", you call the factory method. Instead of calling "delete obj" you call Release.
To do this, you have to follow a few rules. You must use the factory method to create, and use the release method delete. This is to keep the memory allocator happy.
You can expand on the factory method by passing in an argument to select the type of object to return.
MyObject* obj = (MyObject*) CreateObject( MY_OBJECT_TYPE );
CreateObject figgures out the correct object to create/return based on the supplied argument. The supplied argument could be an enum if you are returning a fix number of known object types. You could alternatively pass in a string to match against and build a look up table to match against.
hmod = LoadLibrary("some.dll");
Fn CreateObject = (void* (*(char*)) )GetProcAddress( hmod, "CreateObject");
CreateObject("MyObject);