we have built XLL in C# using ExcelDna as described in https://excel-dna.net/ --- everything works when tested from Excel.
We would like to be able to use this XLL in other .NET projects -- in other words, how do we "host" this XLL from .NET? The XLL does not appear to be a
valid .NET assembly -- so I cannot add it as a .NET reference to other projects
Is it done through ExcelDna.Integration dll somehow (which IS a .net assembly)?
Thank you
Excel-DNA is just a glue between Excel and .NET assemblies.
If you want to reuse functionality that is inside a .NET assembly that is being loaded by an Excel-DNA Add-In (i.e. XLL), then you don't need the XLL for anything... All you need is the .NET assembly that the XLL is loading - Add a reference to that in your .NET application and you're good to go... Just like you would do with any other class library.
In other words, inside your .dna file that is used by Excel-DNA to determine what to load, you have something that looks like this:
<DnaLibrary Name="Your Add-In" RuntimeVersion="v4.0">
<ExternalLibrary Path="YourAssembly.dll" ExplicitExports="false" ... />
</DnaLibrary>
YourAssembly.dll is already the .NET assembly that contains the functions that are exposed to Excel-DNA.
More importantly, if you know you're going to have different .NET "clients" for your functions, then you should design for that, isolate the reusable functions in a dedicated assembly, and have your Excel-DNA assembly reference that, and expose the functions to Excel, instead of forcing clients to depend on Excel-DNA assemblies.
e.g.
C# Class Library Functions.dll (does not reference anything)
C# Class Library ExcelAddIn.dll (references Functions.dll)
C# App MyCsApp.exe (references Functions.dll)
C# Class Library FunctionsComInterop.dll (references Functions.dll)
C++ App MyCppApp.exe (calls FunctionsComInterop.dll)
etc.
In the example above:
Functions.dll does not reference any Excel-DNA assembly and it does not expose anything via to COM. It should have as little dependencies as possible (ideally none!)
ExcelAddIn.dll makes the bridge to Excel-DNA and exposes Excel functions that can be called by Excel through Excel-DNA. These functions simply forward calls to the Functions.dll assembly... Nothing more.
FunctionsComInterop.dll makes the bridge to C++ and exposes COM functions that can be called by the C++ app. These functions simply forward calls to the Functions.dll assembly... Nothing more.
Related
I need to reference two assemblies in my .NET program:
The first assembly, namely ILNumerics, directly references native hdf5.dll library (version 1.8.17) by mean of dllimport("hdf5.dll") platform invoke.
The second assembly, of my own, is a .net wrapper on top native matlab runtime libraries, but this native runtime also internally makes use of native hdf5.dll library (version 1.8.12) [required when working with hdf5 data from matlab side].
Note also that native hdf5.dll library also depends on hdf5_hl.dll and zlib.dll.
I have tried to keep only one version of hdf5.dll library and dependencies and also to set environment variable HDF5_DISABLE_VERSION_CHECK to 2 when starting my application but I can't escape from abrupt crash as I need to use hdf5 handling from both ILNumerics and Matlab runtime sides.
Is there a way I can cheat "dllimport("hdf5.dll")" in ILNumerics assembly to alias some other name ? Note, I don't have the sources, so i cannot hard recompile with dllimport("hdf5_1_8_17.dll"), same for matlab runtime library, I cannot changed anything in it (again third party + native code). What about, in case cheating hdf5.dll name in ILNumerics would be possible, the indirect reference to hdf5_hl.dll from hdf5.dll ?
I guess my only last option is to use load ILNumerics and Matlab runtime assemblies in different applications domains, but then this would be "hell" because I will need to serialize data when calling one or another assembly exposed routine, right ? (I have never worked with separate application domains)
I have a .net 4.0 dll it has a namespace and in that namespace there is a class, I wants to access procedures inside that class using jna.
I have included jna.jar as well as platform.jar(in case) using maven,
My java code looks like this
MyConfiguration interface
import com.sun.jna.Library;
public interface MyConfiguration extends Library{
public void callInterface();
}
Accessing dll code
MyConfiguration myAPI = (MyConfiguration) Native
.loadLibrary("dll/MyAPI.dll", MyConfiguration.class);
System.out.println("Interface Created");
System.out.println("Calling Interface");
myAPI.callInterface();
but i am getting the exception--->
Exception in thread "main" java.lang.UnsatisfiedLinkError: Error looking up function 'myInterface': The specified procedure could not be found.
at com.sun.jna.Function.<init>(Function.java:208)
at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:536)
at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:513)
at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:499)
at com.sun.jna.Library$Handler.invoke(Library.java:199)
at com.sun.proxy.$Proxy0.myInterface(Unknown Source)
at foo.App.main(App.java:83)
I have checked the dll using dll decompiler tool, and it has the called function, can somebody help out.
dll using dll decompiler tool
You need to use a PE (portable executable) viewer to look for entries in the export table. (Depends is one.)
Most .NET DLLs don't export functions that way. When they do, it's through a mechanism called Reverse P/Invoke, which isn't supported by most Microsoft .NET language compilers. The C++/CLI language was designed for this purpose.
You might find a shorter path to success with a Java-.NET bridge product. Or, a Java-COM bridge product if the .NET DLL exposes classes as COM objects. (Use OLE/COM Object Viewer to inspect a COM DLL.)
Also, be sure the DLL has the same bitness as your JVM process (e.g., java.exe or javaw.exe), unless you are using as an out-of-process COM object.
I'm trying to add Windows/System32/Shell32.dll DLL to my project. The issue is, it copies the reference to the directory! Since this is a windows file, it shouldn't have to come with me if I were to deploy my application.
I have tried stopping it from copying to the directory, tried looking for how to embed the resource in the application and even added reference paths to System32. It seems so much more challenging than the program just using the local DLL from the system...
What can I do?
Shell32.dll is a COM component. You should not get a copy of it in your project. What you get instead is Interop.Shell32.dll. Which is a .NET assembly, not a copy of Shell32.dll. It contains the COM interface and class declarations, converted from the type library definition inside Shell32.dll to friendly .NET declarations that the CLR knows how to easily handle.
This is an optimization, it avoids having to make the conversion at runtime. Which is expensive, subject to various options (check the MSDN docs for Tlbimp.exe) and may easily fail because there is no general requirement that the type library is also available on the target machine.
You must deploy Interop.Shell32.dll to the target machine, just like you do with any .NET class libraries you'd use.
Do note that this interop library is no longer needed on .NET 4 and VS2010. Which acquired the "Embed Interop Types" feature. In other words, instead of keeping the interop types in a separate assembly, the C# and VB.NET compilers can now embed them in your program. Very highly recommended, just set the option to True in the Properties window view of the Shell32 reference.
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.
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