Include external dll in type library - c#

I have created a project with some ComVisible methods. To have these available in VBA with Intellisense, I mark the assembly as ComServer in the .dna-file, and generate the .tlb-file using RegAsm in a post-build event. This works great.
I also have another project, that has some ComVisible methods. I would like to have these methods included in that same type library as well. Is this somehow possible?
I thought I could very easily just embed the assembly, which would then do the trick. This is unfortunately not possible. So... any other way I could do this?

Related

Assembly throughout two projects

I want to separate the logic from the GUI in my project. I built a class library and an application, both with the same AssemblyName and Namespaces. When I reference the DLL in my application, I still can't use my internal classes. What should i exactly do?
I have tried setting the ComVisible to true but it didn't work.
Should I have all my classes as public?
I achieved what i wanted and this is how.
Expand the properties in the solution explorer and open AssemblyInfo.cs and use this line of code.
[assembly: InternalsVisibleTo("NAME_OF_NAMESPACE")]
This way i was able to deal with my internal classes that were in my DLL project from the other GUI project.

How to merge F# and C# assemblies with ILMerge so that all types would be available when referenced?

I have a solution with many F# and C# projects. My goal is to merge them all to one library using ILMerge. Resulting merged dll will be put in a NuGet package and referenced in other projects. However, I'm running into few issues when merged dll is referenced in F# projects.
The problem I have is that if primary assembly given to ILMerge is F# then referencing resulting dll in F# project allows to only access F# types. If C# dll is chosen as primary assembly for merge then extension methods from merged F# assemblies were not available when referencing in F# project. Also modules with AutoOpen attribute were no longer implicitly opened when opening enclosing namespace.
Is there a way to merge F# and C# assemblies so that all types (including extension methods) would be available?
In part of our code base, a big chunk of the library is done in F# and the rest in C#. Both F# and C# code are front facing.
We have a hellish batch file to take care of mergeing and what I see is that we are merging with this code:
echo merging %mergeapp% /keyfile:"%keyfile%" /target:library /attr:"%dstpath%%csharpdll%" /targetplatform:%targetplatform%,%targetlib% /lib:%sllib% /lib:%targetlib% /lib:"%libpath%lib" /out:"%mergedpath%..\%csharpdll%" "%dstpath%%csharpdll%" "%dstpath%%fsharpdll%"
%mergeapp% /keyfile:"%keyfile%" /target:library /attr:"%dstpath%%csharpdll%" /targetplatform:%targetplatform%,%targetlib% /lib:%sllib% /lib:%targetlib% /lib:"%libpath%lib" /out:"%mergedpath%..\%csharpdll%" "%dstpath%%csharpdll%" "%dstpath%%fsharpdll%"
and that does what we intend. However, we do not publish any extension methods nor do we do any AutoOpen. What we discovered was a bug in the F# compiler that, up until we started putting obfuscation in the mix, required us to run ildasm on the F# assembly and rip out the offending code. The other issue is that F# doesn't properly support the protected modifier on members (F# makes them public) so we created an attribute that we could hang on class members that were meant to be protected. Then we wrote a tool that uses Cecil to blow the assembly apart, rip out our attribute and change the access to those members to protected (code is in the accepted answer here).
I didn't know about AutoOpen, but I had to do a similar task, so I created class called a registrant that did that kind of work like this:
type FSharpRegistrant() =
do
// do whatever I need to get going
Then in a static constructor within the C# module, I wrote some code that instantiates the F# registrant using reflection to find the class (since in my code base the C# code builds first and doesn't know there's F# code at all). This is ugly code with a lot of error checking, but it works.

How to use tlb file in 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.

C# DLL noob, how to get functions

I've been given a dll to talk to a device, I have little to no experience in C# and I'm supposed to get the device initialized by the end of the week. The dll has methods to open ports and send messages, but I have no idea how to get access to the functions
I know its a bit ridiculous to ask but im running out of time.
Thanks,
Add a Reference to the .dll file in your C# project.
Add a Using namespace at the top of whatever class is going to interact with the .dll methods.
You will now be able to access the methods.
Edit: If your library is unmanaged you'll have to use Pinvoke.
Generally speaking, a feature to call from managed code into unmanaged code (which I assume your DLL is) is called P/Invoke and generally involves annotating required static extern methods with attributes.
Add a reference to the dll in your project (selet browse to find it) and you should be able to access the functions within. As for how to make your device work with it, I think you're on your own :)
If the DLL is a .Net assembly, you can load it into a Visual Studio project by adding it as a reference.
In the absence of documentation, it can also be extremely helpful to load the assembly into .Net Reflector, which lets you inspect the guts of the assembly, even to the point of disassembling the code inside the methods.
1- If it is managed Dll , i.e. Written using .net framework than calling a method from the dll is like you are calling a method from your own class.
just add the reference of the dll in your project and include the namespace reference by 'Using' keyword.
2- If it is not than you need to import your dll dynamically, you can use [DllImport]

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).

Categories

Resources