I have to use a VB (COM) DLL in a C++ DLL. I figured out how to access the VB (COM) DLL from the C++ DLL and it works.
Now I\'ve got the problem that I have to use i
You should use resource id #2 for DLLs, so change your execution of mt.exe to use #2 instead of #1. At least it is so for native DLLs, I'm not sure it has to be so for managed DLLs, so try it out.
You should move everything about the VB.NET DLL, except the dependency, to the VB.NET manifest, as that's the right place to keep that information.
You should use clrClass nodes, instead of comClass nodes, for .NET COM classes.
You may need to generate a type library (tlbexp.exe), and declare it in the manifest (optionally, you may also embed it in the DLL, but I advise against this if the DLL itself is big), if you want your classes and interfaces to be inspectable and marshalable by type library consumers, e.g. VBA, VC++ #import
directive and code generators in general. On top of this, you may need to declare exported interfaces in the manifest, if you create objects outside VB.NET that implement its exported interfaces and which must me marshaled.
If your library is the sole generator of objects that implement the exported interfaces used in the same apartment, you don't need to generate nor declare a type library. I think .NET implements IMarshal
, so this particular scenario works without a type library.
AccConn.manifest:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32"
name="AccConn"
version="1.0.0.0" />
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32"
name="AccConnVB"
version="1.0.0.0" />
</dependentAssembly>
</dependency>
</assembly>
AccConnVB.manifest:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32"
name="AccConnVB"
version="1.0.0.0" />
<file name="AccConnVB.dll" />
<clrClass clsid="{70da7ef0-1549-4b27-9b00-ade5f37aecbe}"
name="AccConnVB.tables"
progid="AccConnVB.AccConnVB"
threadingModel="Both" />
</assembly>
EDIT: According to your question's update.
You don't have a dependency element on the C++ manifest, so it doesn't know about the VB.NET assembly COM-wise without registration.
It seems you're declaring the VB.NET type library in the C++ manifest.
It seems you're declaring a comClass
in the C++ manifest that's declared as a clrClass
in the VB.NET manifest. Don't do this!
You are making an oddly common mistake, expecting Windows to solve the chicken-and-egg problem. A brief word about the way manifest works might help.
Windows loads the content of a manifest when it load an executable file, the entries are added to an internal lookup table. Whenever an application first asks to create a COM object, underlying call is CoCreateInstance() which supplies the CLSID guid, it first consults that lookup table. If the CLSID is a match then the entry tells it what DLL must be loaded. If there is no match then it falls back to the traditional registry lookup.
The chicken-and-egg is that your DLL didn't get loaded yet. So its manifest entries are not yet active.
The egg must come first, the <clrClass>
entry needs to go into the manifest you embed in the C++ executable. Like this:
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="AccConn" version="1.0.0.0" />
<file name="foobar.dll"/>
<clrClass ...etc>
</clrClass>
</assembly>
MSDN article is here.