How to use tlb file in C? - c#

tlb file(using regasm) is made from a dll(using c# code), and i can use this in c++ using #import. and everything is working fine.
Is there a way, i can use this in C language? I just found that #import is c++ specific. So, can someone please tell me how can i use in my C program?
my main intention is to use COM DLL developed in C# in my C program.
Thanks & Rgds,
~calvin

COM programming in C is very painful, but not impossible. The buck stops here though. The point of a type library is to have a tool auto-generate the COM interface and co-class declarations so that you can use them in your code. Quite similar to a .h file, but language independent. The .NET equivalent is the metadata in an assembly.
Problem is, the tooling isn't available to convert a .tlb to C declarations. I'm sure you are familiar with #import, that's what gets used in MSVC. But it generates C++ code, smart pointers that help you create the COM object, call its interface methods and deal with errors. If there is a tool available that generates C then it is a very well hidden secret.
One trick jumps to mind, you can use OleView.exe, File + View TypeLib to view the contents of the type library. This view is decompiled into IDL, the interface definition language. You can copy and paste this text into an .idl file and compile it with midl.exe with the /header command line option. This generates a .h file that contains both C++ and the C declarations for the interfaces. Ought to get you close, just make sure that the type library is reasonably stable so you don't have to do this very often.

I also faced the same problem as I need to use tlb file in C. And I think you can check the below link which helps
How to call a COM component in C
Thanks,
sveerap

Neither C nor C++ have an #import preprocessor directive.

You can use regasm with /tlb option to register the types in windows registry. After that, you can create your instances like regular COM calls from C++ code.
From MSDN:
When you specify the /tlb option, Regasm.exe generates and registers a type library describing the types found in the assembly. Regasm.exe places the generated type libraries in the current working directory or the directory specified for the output file. Generating a type library for an assembly that references other assemblies may cause several type libraries to be generated at once. You can use the type library to provide type information to development tools like Visual Studio 2005. You should not use the /tlb option if the assembly you are registering was produced by the Type Library Importer (Tlbimp.exe). You cannot export a type library from an assembly that was imported from a type library. Using the /tlb option has the same effect as using the Type Library Exporter (Tlbexp.exe) and Regasm.exe, with the exception that Tlbexp.exe does not register the type library it produces. If you use the /tlb option to registered a type library, you can use /tlb option with the /unregister option to unregistered the type library. Using the two options together will unregister the type library and interface entries, which can clean the registry considerably.

Related

Importing nested COM references

In Visual Studio 2015 if I create a "class library" C# project and then add a reference to a custom COM DLL (created using VB6), VS will then also automatically add all (?) the COM references that the VB6 DLL depends on.
How does it do this? How can it statically figure out what those references are?
Note -- Our VB6 DLL uses "early binding", but even still there is no equivalent of an imports table for COM items like you would see in a traditional "C" style DLL.
You are actually adding a reference to a type library. It is embedded inside the DLL as a resource. You can see it when you use File > Open > File, select the DLL, open the TYPELIB node. It plays the exact same role as metadata in a .NET assembly, listing the type definitions of the exposed interfaces and classes. It has a binary format, you can decompile it with the OleView.exe utility.
And has dependency info as well, the registry helps to find such dependent type libraries (HKLM\Software\Wow6432Node\Classes\Typelib key). Roughly the same role that the GAC plays in .NET. COM just isn't as different from .NET as everybody assumes :) The first version of the CLR was created by the COM+ group at Microsoft. Eliminating the registration and DLL Hell problems associated with COM were on the top of the todo list.
Type libraries are not exactly legacy, they still play a pivotal role in the brand-new WinRT (aka UWP, aka Modern UI). Which is COM-based at its core, very well hidden. But the olden format was retired because of limitations, replaced by the .winmd format. Which is exactly the same as the .NET metadata format. Any .NET decompiler can show their content.
The reason that Visual Studio type library importer chases type library dependencies is to gather type information to map to .NET.
A type library doesn't have direct dependency information. So this is a very good question: how to track type library dependencies?
The only feasible way to detect type library dependencies is by referring to a type which states the declaring type library.
For instance, if your type library references IXMLDOMDocument in a method's signature, it'll be recorded in a type info record.
You can crawl a type library, by loading one, getting a ITypeLib from it and enumerating ITypeInfos recursively.
You'll eventually see this record. Then, you can get the type's containing type library ID through ITypeInfo::GetContainingTypeLib. If it refers to another type library, you found a dependency.
A crawler may track dependencies all the way until it has no more type libraries to load.
You don't have to crawl every type of every type library to find the strictly necessary set of types, but the job of the type library importer is to mirror type library information to .NET type info and metadata assemblies, so it imports type libraries in full. It's easier to implement, to explain/understand what it's doing and the output is reusable outside the context of the root type library.
If you didn't use early binding, your type library would instead mention IDispatch, IUnknown and/or VARIANT, which would make it impossible to detect any dependency.
You may use registration-free COM in isolated applications to have the dependencies sorted out, but it still doesn't have to be a proper dependency tree, e.g. you may state all dependencies in one manifest.
And remember that type library != DLL. A type library may be embedded as a resource in a DLL or in its own TLB file.
So, this whole talk is about type dependencies, not class/component or other runtime dependencies.
I don't think it is actually statically analyzing all the dependencies.
I think it is just adding the COM references which are part of the public API of the DLL. These would be plainly visible in the typelib which is part of the DLL, as far as I understand it.
Probably other dependencies which are used internally but not in the public interface are neglected.

(How) can I export a function from a .NET assembly without using C++/CLI?

I'm working on a C# component which consists of two DLLs:
A .DLL written in C++/CLI exporting a symbol; unfortunately, this DLL dynamically links against the CRT and there doesn't seem to be a way around that.
A C# assembly.
The C++/CLI DLL gets loaded and then loads the C# assembly (and forwards most calls to it). Is it possibly to simplify this scenario so that I export a symbol from the C# assembly right away?
You can export your functionallity from C# as a COM server this way it should be pretty easy to call it from C++ as you would do with any other non-C# COM object.
I ended up going for the solution described in http://www.codeproject.com/Articles/37675/Simple-Method-of-DLL-Export-without-C-CLI
The general approach is to have a dedicated attribute which is used to decorate the functions to be exported. After building the assembly, ildasm is used to disassemble it. The resulting IL is patch a little bit so that the previsouly decorated functions are exported, then the IL is assembled into an assembly again.

How can I generate C# source code for a COM Interop library instead of an assembly?

When importing a COM library (either directly with tlbimp, or indirectly with visual studio add reference dialog,) is there a way to generate C# source code instead of a binary interop assembly, like Interop.Word.dll, for example?
UPD: Reflector is bad idea. Problem is that for the com interface is not only a signature, but the order of the members. Reflector this order is violated
I would go ahead and generate the interop assembly using TLBIMP, and the use Reflector to disassemble it. The interop assembly has no actual implementation code, as you will see. You can then just copy and paste the code (or the CoClasses and interfaces you need) into a new .cs file in your project.
You cannot generate C# directly, but if your real problem is that you have a need to tweak the interop library then you might have better luck using the CLR Interop team's custom TLBIMP tool on codeplex - it's pretty flexible and you have full source [to it.]
http://clrinterop.codeplex.com/releases/view/17579
Update: If you're really trying avoid shipping binaries, then you could feasibly integrate the above tool (in source format) into your project so that you generate this interop library at runtime. Result? No binaries to ship.
In general it cannot be done. C# does not support all possible constructs needed to create a working interop assembly. You cannot add e.g. attributes to return types or method parameters in C# although they are needed sometimes to help the marshaller to correctly translate some C++ types.
Yours,
Alois Kruas

include assemblies via code? C#

In msvc i can write
#pragma comment(lib, "my.lib");
which includes my.lib in the linking stage. In my solution i have 2 projects. One is a class project the other is my main. How do i include the reference dll in code instead of adding the reference in the project?
Contrary to popular belief, it is possible :-)
To statically link .NET assemblies check out ILMerge. It's a utility that can be used to merge multiple .NET assemblies into a single one. Be it an executable or a DLL.
You could create a batch script that packages your assemblies together as a post-build step.
Edit: One thing to note however is that this does not remove the need to reference the library. The reference is still needed in order to compile your code that is dependent the external types. Much like including header files under C(++). By default c# assemblies are independent, there is no linking involved. However the tool I mentioned above allows you to create a new assembly with the external dependencies included.
As far as I know, you can't. If you need to access type that are included in a non referenced assembly, you'll have to use Assembly.Load().
I'm afraid you can't.
You can dynamically load the assembly via Assembly.Load(...) but then you have use reflection to explicitly create each Type you need to use.
I don't think you can include a dll from code without adding a reference. What you can do however is to use reflection to load that assembly and use a type from that assembly.
Assembly.Load() will get you a handle on the assembly and then you should be able to iterate through the types in the assembly.
Managed code doesn't use a linker. The C/C++ equivalent of a reference assembly is the #include directive, you need that in C/C++ to allow the compiler to generate code for an external type. Exact same thing in C#, you can't use an external type unless the compiler has a definition for it. The reference assembly supplies that.
The equivalent of C/C++ linking is done at runtime in a managed program. The JIT compiler loads assemblies as needed to generate machine code.
One thing you can do in a C# program that you can't do in a C/C++ program is using Reflection. It allows you to invoke a constructor and call a type's methods with type and method names as strings. Start that ball rolling with Assembly.GetType() and the methods of the Type class. However, consider a plug-in model with, say, the System.AddIn namespace first.
If you want to load an assembly at runtime, you can use Assembly.LoadFrom(filePath). But that way you are not referencing the assembly, and you can't use strong typing.
For example, you can have different plugins implementing a known interface (the one which is in a separate, referenced assembly), and have them all placed in a folder. Then you can check the folder and load all implementing classes at runtime (like in this example).

How to deploy a COM

I just finished building my new COM project (C#, .NET 3.5). This project will be called by a VFP application. It's working great on my development machine, but now I need to know how to deploy it on the user's machine. Click Once isn't available for this kind of project, so I guess I'm stuck with manually distributing the DLL.
So, where should I put the DLL and how do I register it?
BTW, the 3.5 framework is already installed on the user's machine.
TIA
I've really never used RegSvr32 with .Net assemblies, rather I use the regasm with the /codebase option:
C:\Windows\Microsoft.NET\Framework\v2.0.50727\regasm.exe /codebase mydll.dll
You can also use the /tlb option to export the type library and register it.
Of course the easiest way, just create an installer with vstudio and it will do this for you.
Creating a Description of the COM class and Interfaces
.Net assemblies don't include information in Type Library compatible format. So it is necessary for the programmer to run one of two .Net-supplied utilities to extract the assembly description of a class into a Type Library file.
One utility is TLBEXP.EXE, the .Net Type Library Exporter. This command line utility takes as input the name of an assembly DLL file to be converted to a Type Library. The programmer can also specify the name of a Type Library file to be created.
tlbexp ComServer.dll /out:ComServer.tlb
Assembly exported to C:\Magellan\Source\Output\Debug\ComServer.tlb
Once a Type Library has been created, it can be referenced by a COM client to obtain the information necessary for the COM client to bind to the interfaces of the COM class, and activate the COM class at runtime.
Registration of the COM Class and Interfaces
For a COM class to be accessible by the client at runtime, the COM infrastructure must know how to locate the code that implements the COM class. The following command accomplishes this:
regasm ComServer.dll
Your DLL can be put anywhere you wish, but a good choice is C:\Program Files\MyApplication.
http://www.csharphelp.com/archives/archive190.html

Categories

Resources