Link to home
Start Free TrialLog in
Avatar of solublefish
solublefish

asked on

TYPE_E_CANTLOADLIBRARY #importing my DMO .dll

I have a simple audio effect COM component built in VC++ (6.0).

It seems to successfully register, showing no error after build, and saying "DllRegisterServer in c:\importcomponents\binrawdmo.dll succeeded" when using RegSvr32.

But I can't seem to do several other things with it:
#import in C++: #import "<rawdmo.dll>"
(gives "fatal error C1083: Cannot open type library file: 'c:\importcomponents\bin\rawdmo.dll': Error loading type library/DLL.)

CreateObject in VB:
    Dim foo As Object
    Set foo = CreateObject("DMO.RawDMO")
(Gives "Object Required" A watch on CreateObject("DMO.RawDMO") indicates "Variant/<Unsupported object type>")

OleView: View TypeLib
(Gives "LoadTypeLib(C:\importcomponents\bin\RawDMO.dll) failed. Error loading type library/DLL TYPE_E_CANTLOADLIBRARY ($80029C4A)" )

The component is a DirectX Media Object built in VC++ using the "Audio Effect DMO Wizard" from the DirectX SDK. If I make a new project with the wizard and compile it, I get the same problem, indicating that it's not due to my small amount of customization.

The defaults DLLRegisterServer has two things.
1.A call to
DMORegister(), which sets up the DirectX registration required. That seems to work fine, since I can load and use the DMO in Windows Media Encoder.

2. return _Module.RegisterServer();
If instead, I call _Module.RegisterServer(TRUE); (setting bRegTypeLib TRUE to register the typelib),
I now get the same behavior except I also get the TYPE_E_CANTLOADLIBRARY error when using Regsvr32.
}
Avatar of solublefish
solublefish

ASKER

Alternatively, points for anyone who can point me to resources on how to implement a DMO in .NET managed code. All the MSFT resources seem to only be for C++
Chances are the generated type library is not being inserted as a resource within the dll, which is the norm.

Is there a stand-alone .tlb file within the build directory itself? If so, this needs registered as a distinct entity, besides registering the dll.
There's no .tlb file being generated.
For lack of any other ideas, I'm in the process of trying to "port" the class definitions to IDL and get one that way, but it's slow going and I'd really rather have an automatic one.
If the only interfaces you're exposing are from the DirectX media library you may be able to circumvent the creation of your own type library.


Dim foo As Object     <-- instead of Object (which equates to IDispatch) try Dim'ing this an underlying DirectX media interface
Set foo = CreateObject("DMO.RawDMO")

Sorry, but I don't have the SDK installed so cannot give you an exact project reference / type.
   Good idea, but I'm afraid I need to expose an interface of my own. The situation is as follows. My driver program instantiates a Windows Media Encoder and tells it to load the DMO (by name). Then I need to call some proprietary methods on the loaded plugin to configure it and feed it some data.
    The WMEncoder object will give me an IUnknown pointer to my DMO class, but I need to be able to call methods of its IRawDMO interface (defined by me). I can even QueryInterface for it by manually defining the IID in the driver project, but the driver project still doesn't know the method signatures of IRawDMO.
    Besides, if other developers are to use the RawDMO in their projects, they'll want to be able to just #import it.
Let me ask this - If I finish the .idl and get a valid .tlb file, how do I then add it to the .dll resources so that #import will work?
ASKER CERTIFIED SOLUTION
Avatar of _ys_
_ys_

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
> You can use #import on a dll as well.

Oops. I meant to say:
You can use #import on a .tlb as well.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
OK, this is good. I finished the .idl (more or less) and have a .tlb.

I think I would like to encapsulate it in the .dll. We have a fair number of VB and .NET developers around here, and my library is just going to be easier for them to use if it's in one piece. I've used your technique to add the typelib info to the resources, but then I have to repeat that process every time I change the idl. Is there way to make MIDL do it automatically?

Btw, thanks for the note about changing the ID to 1. I never would have figured that out, and it seems to be required for OLEView to pull it out of the .dll
I usually don't embed the type library into the dll in the first place, so I've never be too bothered about manaully doing it with each build. Besides how often does the type library change. Saying that I have been the recipient of a customer's dll which was nearly always out of sync. Due diligence.

If you really wanted to you could always record a macro via the IDE to perform this for you.

The id of 1 I do have experiences with. Took a while to figure out as well. But at least now you know.

As a side note, you can embed multiple type libraries within a dll. You can then specify which one you want to import with the #import statement.

#import "rawdmo.dll"#1
#import "rawdmo.dll"#2
etc.

I don't recommend you do. It's just FYI only.
It turns out you can automatically add/update typelib info by putting a line like:
1 TYPELIB "./Debug/foobar.tlb"
to your .rc file. VCC then reimports the .tlb every time it builds.
Thanks for the tip. I'll remember that.