Creating a simple c# dll and access it from ruby - c#

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

Related

Access .net dll through JNA in java

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.

How can a C# program use a C++ dll of any version?

We're creating a dll, written in C++, providing access to some hardware. We also have a C# program that uses this dll.
We're having an issue with the versions. Indeed, when running the C# program, it absolutely wants to use the exact C++ dll version it used when compiling. I.e. if the C# program was compiled using C++ dll 1.2.3.4, then the program will refuse to run with C++ dll 1.2.3.5.
I'd like to instruct the C# program to use any C++ dll with version 1.2.anything.
Where can I configure this in the C# project?
This question has been superseded by that one, more related to COM.
Nothing this fancy exists in C++. Using a side-by-side manifest technically permits this but you would have known about it since you would have typed the version number in the manifest of your C# program.
The far more likely explanation is that you actually created a C++/CLI assembly. Many programmers confuse C++/CLI with C++. Easy mistake since that language permits using native C++ code. But it actually gets compiled to a mixed-mode assembly, an assembly that contains both IL and native code. The normal CLR version checking occurs for such an assembly when the CLR loads it, it is only happy with an exact version match. A strong DLL Hell counter-measure.
And the normal CLR version wrangling option is available to bypass this check, a <bindingRedirect> element in your app.exe.config file. As well as controlling the assembly version number the way you do it for your C# code so this isn't necessary.
The easiest way to check if this guess is accurate is by using Project + Add Reference and select the DLL. If that doesn't draw any complaint and the assembly gets added to the References node of your C# project then you know it is a normal .NET assembly. Don't forget to take advantage of that, no pinvoke required.
Load the dll at runtime and use reflection to call it's methods.
Assembly assembly = Assembly.LoadFrom("C:\\test.dll");
Assembly.GetTypes();
Activator.CreateInstance(type);
I don't think it is possible to configure your program to use 1.2.* version and no others. Unless you would write the code for that on your own. Another possibility would be not to change the version tag of the C++ dll, but it does not seem you want to that.
A solution avoiding the version dependency would be the usage of dllimport. You can load any dll written in C++ with it. It is free of version dependency. See the example from the msdn and link at the end:
using System;
using System.Runtime.InteropServices;
class Example
{
// Use DllImport to import the Win32 MessageBox function.
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern int MessageBox(IntPtr hWnd, String text, String caption, uint type);
static void Main()
{
// Call the MessageBox function using platform invoke.
MessageBox(new IntPtr(0), "Hello World!", "Hello Dialog", 0);
}
}
Description in MSDN

C# DLL Import with VC++

I am new to Visual Studio 2010,
I have the DLL written with C# , and it is working with VB.NET , Now I want to use it with VC++, Can you help me ?
If you are planning on using .NET extensions in your VC++ project, you just need to add a reference to your C# DLL in your VC++ project.
If you're planning to use pure C++, you'll need to change your C# DLL to be COM-Visible, and generate a typelib that you'll import in your C++ project.
You can access functions from native DLL (written in C++) from .NET using PInvoke. To use managed DLL from native code (eg. call C# method from C++ code) you have to wrap managed code in COM component and use that COM object from C++
Going the other way is easy using P/invoke. Calling managed code from unmanaged is tricker. One good option is COM, but there is an alternative. Robert Giesecke has published an excellent project that allows you to expose managed methods as unmanaged DLL exports.
It's very simple to use. You simply download the Visual Studio template, create a project based on that, add your code, and mark exports with the DllExport attribute.
Or you can create Manager C++ DLL that will reference and implement all or custom objects from C# DLL.
After than you can create dllexport methods in your MCPP DLL.
And then you can access C# DLL thru MCPP DLL using LoadLibrary(...)/GetProcAddress(...) methods.
Example:
using namespace System;
using namespace System::Windows::Forms;
__declspec(dllexport) LPVOID GetPluginInterface()
{
return (IWithExecuteCommandMethod*)&theApp;
}
bool CClass::ExecuteCommand()
{
if(Threading::Thread::CurrentThread->TrySetApartmentState(System::Threading::ApartmentState::STA))
{
Flatbed::SomeDialog ^pDialog=gcnew Flatbed::SomeDialog();
pDialog->ShowDialog();
}
else
{
Threading::Thread ^pDialog=gcnew Threading::Thread(gcnew Threading::ThreadStart(ThreadProc));
pDialog->SetApartmentState(Threading::ApartmentState::STA);
pDialog->Start();
}
return false;
}

Accessing C# library from VC++ code

I have windows form application written in VC ++ . I want to change the button click in this app (WInform app in VC++) to hit a function written in C#.
What are the possible ways to do this.
Calling a C# assembly without compiling with C++/CLI is tricky. some of the ideas I've had:
a) Create a mixed-assembly wrapper dll (mixed assemblies contain both native code and managed code). Add a reference to your C# assembly, then create functions in your dll that call the C# code via C++/CLI, then define dll entrypoints ( __declspec(dllexport) ) for those functions. You can now link against the dll as it will provide a native interface that C++ can understand, while internally that dll can call your C# code.
( Afterthought: You can probably compile this to a .lib, that would be easier than a dll.)
Walkthrough: Creating and Using a Static Library
b) Use Mono to call the C# assembly. Mono has a C API which you can use to load and use managed assemblies without using c++/CLI. This is what I would do if C++/CLI is not an option.
Embedding Mono
c) If your function has a relatively simple input/output signature (no large objects, etc) you might consider compiling your C# function into an executable and use standard input/output to call the function. You'll have to carry input arguments and the output as text, though. Then make C++ start the executable and pass some input to it, and read the output.

Calling C# from C

Has anyone worked on calling a C# module from C module. I tried searching on internet but didn't find good examples. Though lot of sites say something like using COM interop but couldn't find a proper example or article explaining it though.
If someone can help me on this, it would be great
Thanks,
Sveerap
There is more than just COM interop if you want to call into managed code from C or C++. The are also the following lesser known methods (taken from MSDN FAQ):
How do I call a .NET assembly from native Visual C++?
There are basically four methods to
call .NET assembly from native VC++ code:
CLR Hosting API: Native VC++ module calls CLR Hosting APIs to host CLR, load and call the .NET assembly (sample code: CppHostCLR).
COM Interop: If the .NET assembly can be exposed as a COM component, native VC++ module can call into the .NET assembly through .NET – COM interop (sample code: CppCOMClient).
Reverse PInvoke: The managed code calls native code passing a delegate that the native code can call back (sample code: CSPInvokeDll).
C++/CLI: If the module containing native VC++ code is allowed to enable CLR, the native VC++ code can call
.NET assembly directly (sample code: Consuming C# Library in native C or C++ using C++/CLI)
Here is a solution. The solution allows calling a C# function from C by decorating your function with [DllExport] attribute (opposite of P/Invoke DllImport).
https://sites.google.com/site/robertgiesecke/Home/uploads/unmanagedexports
C# code
class Test
{
[DllExport("add", CallingConvention = CallingConvention.StdCall)]
public static int Add(int left, int right)
{
return left + right;
}
}
C code
int main()
{
int z = add(5,10);
printf("The solution is found!!! Z is %i",z);
return 0;
}
As #iceflow19 commented below:
The author of the link provides a CLR IL preprocessor as an added step during compilation. Since assemblies use the same binary container format (DLL) on windows, if you manually add the .Net functions offsets in IL to the vtable (the dll's list of exports), Windows is smart enough to invoke the CLR to run that code when called from C. However there is overhead. It's an unadvertised feature. This is how mixed managed libraries in C++/CLI work. To use it just add it through Nuget. The extra target added in your MSBuild project file will provide for the IL preprocessing step
You could expose your C# module as COM:
http://www.codeproject.com/KB/cs/ManagedCOM.aspx
Best method of calling managed code(c#) from unmanaged C++
http://www.codeproject.com/KB/COM/cominterop.aspx
There is also the option of building native libraries from C# code using CoreRT and call them from C.
Here is an example.
Edit: CoreRT has moved to runtimelab feature NativeAOT. Updated link.

Categories

Resources