[Wrapper Assembly For Type Library: Best Practices and Tips](^3^)
- demetricemehrhoff8
- Aug 19, 2023
- 5 min read
Warning 5 Cannot find wrapper assembly for type library "DAO". Verify that (1) the COM component is registered correctly and (2) your target platform is the same as the bitness of the COM component. For example, if the COM component is 32-bit, your target platform must not be 64-bit. Rooster programmaWarning 1 Could not resolve mscorlib for target framework '.NETFramework,Version=v4.0,Profile=Client'. This can happen if the target framework is not installed or if the framework moniker is incorrectly formatted. 0 0 Warning 4 Could not resolve mscorlib for target framework '.NETFramework,Version=v4.0,Profile=Client'. This can happen if the target framework is not installed or if the framework moniker is incorrectly formatted. 0 0 Warning 3 The referenced component 'DAO' could not be found. Error 2 Unable to find manifest signing certificate in the certificate store. Rooster programma
You may startwriting new .NET applications (or porting Win32 COM applications over to .NET)and need to access existing COM objects from within them. In order for .NET touse a COM object, wrapper objects called Runtime-Callable Wrappers (RCWobjects) need to be generated. These wrapper objects cater for the differencein lifetime management between .NET and COM. RCW objects are .NET objects thatmanage the reference count of a COM object as well as dealing with themarshaling of parameters and return types for the COM object methods.
Find Wrapper Assembly For Type Library
RCW objectsare manufactured at runtime by the CLR using information found in an InteropAssembly (an assembly containing definitions of COM types that can be usedfrom managed code). You use a type library importer to scan the COM server typelibrary and generate appropriate .NET-compatible information in an InteropAssembly for your COM server.
The typelibrary importer can be invoked from a utility, Tlbimp.exe, that is suppliedwith the .NET Framework SDK. You can also do it under program control using theTypeLibConverter class in the System.Runtime.InteropServices namespace. However itis most common to have your IDE do the work for you, saving you from having toworry about the details.
To generate anInterop Assembly for the SAPI 5.x COM server you simply need to add a referenceto its type library into your project references, in much the same way asadding a reference to a regular .NET assembly; by right-clicking on the References node in the ProjectManager and choosing Add Reference, or by selecting Project AddReference...In the Add Reference dialog the .NETAssemblies tab is selected by default but the COM Imports tab allows you to locate type libraries.
All registeredtype libraries will be displayed, listed by the help strings (the Delphi 7 TypeLibrary Editor allows you to set this for Delphi COM servers). If your COMserver has not been registered, thereby meaning its type library has not beenregistered, you can still find it with the Browse... button.
Notice thename of the Interop Assembly follows a convention used by the popular IDEs. Delphi for .NET uses the Interop prefix convention, which seems descriptive enough forInterop Assemblies that describe custom COM servers. The other half of theassembly name is typically set to the library name, as found in the typelibrary. If you open the type library in Delphithe top level node in the Type Library Editor tells you the library name. Bydefault, Delphi-written COM servers use the project name, but this is notalways the case as you can see with the SAPI type library; the COM server iscalled sapi.dll but the type library is called SpeechLib. Inside the InteropAssembly will be a namespace named after the type library, which will be SpeechLib in this case.
Note: the type library importer makescertain assumptions about the use of parameters and sometimes will useparameter types that are not the most appropriate. The warnings in the outputabove suggest that in this case it could not even decide how to deal with themarshaling requirements in cases. You can modify the results of the importprocess using creative round tripping against the Interop Assembly. Thetechnique of creative round tripping is discussed in Reference 1 and Reference3.You can also find mention of it, along with advice on how to resolve commonInterop Assembly errors in Reference 4.
The mostcommon requirement will be to use early binding to get compile-time type checkingand direct (well, as direct as it gets) vtable calls to the COM objects. Theexample above took this approach. As long as you know the namespace in theInterop Assembly and the types you need to define, you should find the CodeCompletion will answer questions about which methods can be called and whichparameters need to be passed.
Setting upevent handlers for COM object events is much the same as for any other object,as the Interop Assembly defines delegate types for all event methods, andimplements helpful add and remove routines in the events interface wrapper. Inthe Speech API case mentioned above the realevents interface is called _ISpeechVoiceEvents but the Interop Assembly definesa wrapper interface called _ISpeechVoiceEvents_Event.
All you needto know in order to write event handlers for COM events you need to know aboutthe delegate types present in the Interop Assembly. Once you have theinformation it is simply a case of implementing a compatible routine and using Include to add it to theappropriate event. Using Include adds your handler to the potential list of otherhandlers; .NET events, as implemented by delegates, support event handlermultiplexing. The add/remove routines in the generated wrapper interface areused to insert/remove your handler in/from the list when using Include/Exclude.
We can use the.NET Framework SDK IL Disassembler utility (ildasm.exe) to examine the delegatetypes (see note above regarding using the SDKtools. In the original type library the events interface was called _ISpeechVoiceEvents and the pertinent methods are called Word,EndStream and AudioLevel. When the type libraryimporter manufactures the Interop Assembly it creates delegate types with namesin the form: SourceInterfaceName_MethodNameEventHandler so the specific delegate types we need will therefore be called _ISpeechVoiceEvents_WordEventHandler, _ISpeechVoiceEvents_EndStreamEventHandler and _ISpeechVoiceEvents_AudioLevelEventHandler. If you locate one of these delegates in ILDasm you can see theclass inheritance and the presence of the custom Invoke method.
System.TypeInitializationException: The type initializer for 'RuntimeCoreNet.GeneratedWrappers.CoreWrapperBase' threw an exception. ---> System.Exception: Failed to initialize ArcGIS Runtime core. The ArcGIS Runtime core library is inaccessible. ---> System.DllNotFoundException: libRuntimeCoreNet assembly: type: member:(null) at (wrapper managed-to-native) RuntimeCoreNet.GeneratedWrappers.CoreArcGISRuntimeEnvironment.CoreRT_ArcGISRuntimeEnvironment_enableBreakOnException(bool,intptr&) at RuntimeCoreNet.GeneratedWrappers.CoreArcGISRuntimeEnvironment.EnableBreakOnException (System.Boolean enable) [0x00000] in :0 at Esri.ArcGISRuntime.ArcGISRuntimeEnvironment.Initialize () [0x0007d] in :0 --- End of inner exception stack trace --- at Esri.ArcGISRuntime.ArcGISRuntimeEnvironment.Initialize () [0x000db] in :0 at Esri.ArcGISRuntime.ArcGISRuntimeEnvironment.OnBeforeFirstUseOfGeneratedWrapper () [0x00013] in :0 at RuntimeCoreNet.GeneratedWrappers.CoreWrapperBase..cctor () [0x00000] in :0 --- End of inner exception stack trace --- at RuntimeCoreNet.GeneratedWrappers.CorePortal..ctor (System.IntPtr handle) [0x00000] in :0 at RuntimeCoreNet.GeneratedWrappers.CorePortal..ctor (System.String uRL) [0x00000] in :0 at Esri.ArcGISRuntime.Portal.ArcGISPortal.CreateUnloadedPortal (System.Uri portalUri, System.Globalization.CultureInfo culture) [0x00010] in :0 at Esri.ArcGISRuntime.Portal.ArcGISPortal.CreateAsync (System.Uri portalUri, System.Boolean loginRequired, System.Globalization.CultureInfo culture, System.Threading.CancellationToken cancellationToken) [0x00019] in :0 at VertiGIS.Mobile.Modules.GenericApp.WelcomeViewModel.InitializeAgolPortalExtension () [0x00092] in :0 at VertiGIS.Mobile.Modules.GenericApp.WelcomeViewModel.ExecuteSignInToAgolAsync () [0x00087] in :0 [2020-09-14 13:57:01,920][ERROR] System.TypeInitializationException: The type initializer for 'RuntimeCoreNet.GeneratedWrappers.CoreWrapperBase' threw an exception. ---> System.Exception: Failed to initialize ArcGIS Runtime core. The ArcGIS Runtime core library is inaccessible. ---> System.DllNotFoundException: libRuntimeCoreNet assembly: type: member:(null) at (wrapper managed-to-native) RuntimeCoreNet.GeneratedWrappers.CoreArcGISRuntimeEnvironment.CoreRT_ArcGISRuntimeEnvironment_enableBreakOnException(bool,intptr&) at RuntimeCoreNet.GeneratedWrappers.CoreArcGISRuntimeEnvironment.EnableBreakOnException (System.Boolean enable) [0x00000] in :0 at Esri.ArcGISRuntime.ArcGISRuntimeEnvironment.Initialize () [0x0007d] in :0 --- End of inner exception stack trace --- at Esri.ArcGISRuntime.ArcGISRuntimeEnvironment.Initialize () [0x000db] in :0 at Esri.ArcGISRuntime.ArcGISRuntimeEnvironment.OnBeforeFirstUseOfGeneratedWrapper () [0x00013] in :0 at RuntimeCoreNet.GeneratedWrappers.CoreWrapperBase..cctor () [0x00000] in :0 --- End of inner exception stack trace --- at RuntimeCoreNet.GeneratedWrappers.CorePortal..ctor (System.IntPtr handle) [0x00000] in :0 at RuntimeCoreNet.GeneratedWrappers.CorePortal..ctor (System.String uRL) [0x00000] in :0 at Esri.ArcGISRuntime.Portal.ArcGISPortal.CreateUnloadedPortal (System.Uri portalUri, System.Globalization.CultureInfo culture) [0x00010] in :0 at Esri.ArcGISRuntime.Portal.ArcGISPortal.CreateAsync (System.Uri portalUri, System.Boolean loginRequired, System.Globalization.CultureInfo culture, System.Threading.CancellationToken cancellationToken) [0x00019] in :0 at VertiGIS.Mobile.Modules.GenericApp.WelcomeViewModel.InitializeAgolPortalExtension () [0x00092] in :0 at VertiGIS.Mobile.Modules.GenericApp.WelcomeViewModel.ExecuteSignInToAgolAsync () [0x00087] in :0 2ff7e9595c
Comments