Access .net dll through JNA in java - c#

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.

Related

How to use ExcelDNA developed XLL from C# without Excel

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.

Embed native dll or .NET assembly into COM

I have a .NET library and I want to wrap it by COM to invoke its functions from C++. Fortunately, this library is open source and if I add COM-visible class right inside this project - it works:
[Guid("38F752CC-20F1-4729-B1E3-EE0AAD145052")]
public interface IQRCodeUI
{
string GetDecodedString(string encodedString);
}
[Guid("D4CFCDFA-6718-494D-A23F-EBC0F9550377")]
public class QRCodeUI : IQRCodeUI
{
public string GetDecodedString(string encodedString)
{
return decoder.decode(encodedString);
}
}
decoder is a class from this very library.
But what to do in case if I would have compiled assembly? I tried to create class library (COM) and add .NET library as embedded resource to it. Without results! During compile it said something like cannot register assembly "path\name". Cannot load file or assembly "nameOfAssembly" or its dependency. Cannot find the file. Apologise, I can't provide original text of the error, because I have MSVS which language differs from English. Is it possible to resolve this issue?
If your task is to call .NET library from C++ via COM, why you're adding .NET library as an embedded resource into some new COM class library?
Just make existing third party assembly COM-visible and call it from C++, VB6, etc.
There are a number of docs all over the internet of how to make .NET assembly COM-visible. None of them, as I recall, contain recommendations to embed .NET assembly into COM class assembly.
Start with:
Best Practice in Writing a COM-Visible Assembly (C#)

Creating a simple c# dll and access it from ruby

I'm trying to make my first c# dll.
I want to be able to call it's methods/functions from ruby with win32API.
I have made this dll:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ClassLibrary1
{
public class Class1
{
public int PropA = 10;
public void Multiply(Int32 myFactor)
{
PropA *= myFactor;
}
}
}
I compiled it with Visual Studio 2010 and got my ClassLibrary1.dll file.
Now for the ruby part i tried this:
f = "c:/path_to_file/ClassLibrary1.dll"
mult = Win32API.new(f,"Multiply",["I"],"I")
But, i get the following error:
Error: #<RuntimeError: (eval):0:in `initialize': GetProcAddress: Multiply or MultiplyA
To be honest, I never created a dll, nor do I have experience with c#. I just wanted to get started. I have used many dll's with Ruby via win32API before (user32 mostly).
I guess my dll is not ok?
Regards,
To consume functions from DLLs as done in a Win32 context, these functions need to be export-visible from the DLL. These functions are usually flagged with dllexport and will show up in the export table of a DLL. You can verify that user32 and other Win32 DLLs do this by using a utility such as dumpbin (MSDN).
dllexport, dllimport # MSDN
Unfortunately, .NET doesn't have immediate support for making functions export-visible, only for bringing in such functions via the DllImport (MSDN) Attribute.
COM is the easiest way to consume code written within .NET from a non-.NET environment, but if you must use the lower level bindings, you can make an intermediate DLL in C, C++/CLI, or any other language and framework combination that can write export headers to a dll, to call your .NET code.
Also, A few articles exist on making this happen via post-compilation automation or other workarounds, here are a few for your reference.
How to Automate Exporting .NET Function to Unmanaged Programs # CodeProject
Unmanaged Exports # Google Sites
DllExport - Provides C-style exports for pure .NET assemblies
Without doing anything extra, the DLL created is an Assmebly intended to be run inside the .Net runtime (the CLR).
You can expose it through Com as described in the related question: Can Ruby import a .NET dll? which

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.

dll export/import problem in visual studio 2010

I am wrote a visual c++ win32 console app, and i wrote it and tested it in
win32 console project
. then i switch to
win32 project
and imported all the source files and created a dll for it. by mark the class i want to export as
#define DllExport __declspec( dllexport )
class DllExport theClass {
}
it works and the dll is generated. then i created a another c# project and want to add the dll to the project. by reference->add reference-> browser. then i select that dll.
then it is gives me an error
a reference to the '''''''.dll could
not be added. please make sure that
the file is accessible, and that is a
valid assembly or com component.
anyone knows where i did wrong to generate/import the dll?
thanks
The Add Reference dialog can only work for DLLs that contain metadata (managed code) or a type library (a COM server). Your DLL doesn't fit that bill, you can only use the [DllImport] attribute in C# code to use the P/Invoke marshaller to call an unmanaged DLL entrypoint.
That can not be a native C++ class, like you are trying to do, there is no reliable mechanism for managed code to allocate unmanaged memory and call the constructor (and destructor) of a native C++ class. Short from the difficulty of finding the constructor and destructor code, there is no way for the P/Invoke marshaller to know the size of the object. The C++ language doesn't generate the metadata necessary to know this required information.
If you want to pursue P/Invoke then write an plain global function, decorated with extern "C", __declspec(dllexport) and (optionally) __stdcall.
If you want to export a C++ class then the only avenue is using the C++/CLI language and write a "ref class" wrapper for the native C++ class.
Or you could write a COM coclass, the universal glue in Windows. Very well supported by .NET, probably not something you want to pursue if you never wrote COM code before. ATL is the best way to get one going.

Categories

Resources