I recently was looking into something similar, and it turns out it's pretty straight-forward to do. A COM DLL has to export a DllGetClassObject entry among a few others. In general the selected development platform does this for you, but in the final DLL it's right there, both available for use by the COM sub-system, but just as well by yourself with code like this:
type
T_DGCO=function(const CLSID, IID: TGUID; var Obj): HResult; stdcall;//DllGetClassObject
var
p:T_DGCO;
f:IClassFactory;
x:IMyObject;//replace by an interface of choice
begin
p:=GetProcAddress(LoadLibrary(FullPathToDLL),'DllGetClassObject');
if @p=nil then RaiseLastOSError;
OleCheck(p(CLASS_MyObject,IClassFactory,f));
OleCheck(f.CreateInstance(nil,IMyObject,x));
x.Hello('World');//or whatever your object does
end;