Writing a C++ DLL that a C# .NET Application can call? - c#

This is the situation. I am writing a backend application in C++ and my colleagues are using C# for the frontend. Basically, my backend application does image processing on images received from the C# frontend and returns a text file with data about the image.
What we were doing earlier was writing the images to disk and calling the C++ application with the file path of the image as a parameter. However, this writing/reading from disk has become a bottleneck, so we are wanting to convert the C++ application to a DLL.
At the basic level, what I want is to expose a single method from my C++ application to the C# one through a DLL (the C# application is web-based):
int ProcessImage(System::Bitmap^ image, System::String ^results)
How can I go about doing this? I am using VC++ Express 2008 and my C++ code currently compiles with CLR (although I have mixed a lot of native C++ code inside).
I have been looking around on the web, but am still stuck on how to do this. I think a C++/CLI DLL is the best option, but how do I do this?
Writing a DLL in C/C++ for .Net interoperability

If you label your C++ function as a "C" function, then it can be called by PInvoke.
Your C function will look like this:
extern "C" __declspec(dllexport) int Test() {
return 1;
}
Your C# reference will be like this:
[DllImport("test.dll")]
public static extern int Test();
If you C++ function is an instance member, then you can still do it but it requires some tricks.

I finally figured it out. What you need to do is:
In your C++ project, set the option in Visual C++ to compile with clr pure, which makes the project a C++/CLI one
In your C++ project, expose methods by creating a public ref class:
public ref class Interop
{
public:
//! Returns the version of this DLL
static System::String^ GetVersion() {
return "3.0.0.0";
}
//! Processes an image (passed by reference)
System::Int32^ Process(Bitmap^ image);
}
In a C# program, add a reference to the C++ DLL you compiled
In the C# program, call these methods (i.e. Interop::Process(myBitmapInCS))
I believe this method is called "implicit P/Invoke"
Hope this helps!

Related

load C# dll in c++/cli and create a dll that works in unmanaged language

I have written a selenium script in C# and now I want to expose all functions and use them all in c++ code. My point is to deliver a dll to sb who wants to use this dll in pascal (delphi). The C# code is a complete code and all I want to do is to make a bridge between my C# and pascal.
I found out that pascal is an unmanaged language so C# code, which is a managed one, can not be consumed in pascal. For that reason, I started to write a c++ dll that uses my C# dll and makes a bridge between my C# and pascal code.
I've read all available topics on stackoverflow and these are what I've found useful:
expose my functions using COM
using c++/cli to communicate with my C# dll.
I started with the first one. I was able to create COM visible dll and use that in my c++ native code but I had problems with data types. I found it hard and moved on to the second option. But I'm not sure if I can wrap all my functions like that and let unmanaged languages use them.
a sample of my c# code:
namespace MainEngine
{
public static class StartMainEngine
{
public static void test_pascal(out string _result)
{
_result = "Hello World!";
}
}
}
my c++/cli code(I have referenced to my dll and visual studio shows me all functions inside my dll. So, It's not a dll import issue):
#using<ManagedLibrary.dll>
using namespace MainEngine;
char* r;
StartMainEngine::test_pascal(r);
Please guide me through this and let me know if I'm doing this in the correct way to be able to consume this dll in pascal.
It's possible using COM, CLR or IPC
Full answer you can find in this topic here

Calling method from an injected C# using another injected C++ library [duplicate]

I need to be able to invoke arbitrary C# functions from C++. In-process Interoperability suggests using ICLRRuntimeHost::ExecuteInDefaultAppDomain(), but this only allows me to invoke methods having this format: int method(string arg)
What is the best way to invoke arbitrary C# functions?
There are several ways for a C++ application to invoke functions in a C# DLL.
Using C++/CLI as an intermediate DLL
http://blogs.microsoft.co.il/sasha/2008/02/16/net-to-c-bridge/
Reverse P/Invoke
http://tigerang.blogspot.ca/2008/09/reverse-pinvoke.html
http://blogs.msdn.com/b/junfeng/archive/2008/01/28/reverse-p-invoke-and-exception.aspx
Using COM
http://msdn.microsoft.com/en-us/library/zsfww439.aspx
Using CLR Hosting (ICLRRuntimeHost::ExecuteInDefaultAppDomain())
http://msdn.microsoft.com/en-us/library/dd380850%28v=vs.110%29.aspx
http://msdn.microsoft.com/en-us/library/ms164411%28v=vs.110%29.aspx
https://stackoverflow.com/a/4283104/184528
Interprocess communication (IPC)
How to remote invoke another process method from C# application
http://www.codeproject.com/Tips/420582/Inter-Process-Communication-between-Csharp-and-Cpl
Edit: Host a HTTP server and invoke via HTTP verbs (e.g. a REST style API)
Compile your C++ code with the /clr flag. With that, you can call into any .NET code with relative ease.
For example:
#include <tchar.h>
#include <stdio.h>
int _tmain(int argc, _TCHAR* argv[])
{
System::DateTime now = System::DateTime::Now;
printf("%d:%d:%d\n", now.Hour, now.Minute, now.Second);
return 0;
}
Does this count as "C++"? Well, it's obviously not Standard C++ ...
See DllExport.
IOW: The exact opposite of how DllImport works.
https://github.com/3F/DllExport
It has support for Windows, with cross-platform support in the works.
C# code (which we call from C++):
[DllExport]
public static int _add(int a, int b)
{
return a + b;
}
[DllExport]
public static bool saySomething()
{
DialogResult dlgres = MessageBox.Show(
"Hello from managed environment !",
".NET clr",
MessageBoxButtons.OKCancel
);
return dlgres == DialogResult.OK;
}
C++ code (which calls previous C# code):
typedef int(__cdecl *_add)(int a, int b);
typedef bool(__cdecl *saySomething)();
auto pAdd = (_add)GetProcAddress(lib, "_add");
int c = pAdd(5, 7);
auto pSaySomething = (saySomething)GetProcAddress(lib, "saySomething");
bool dlgres = pSaySomething();
And a YouTube video with a demo at Managed & Unmanaged; PInvoke; [ Conari vs DllExport]. To be honest, the documentation is a cut below perfect, but don't let that put you off: the YouTube videos are excellent.
This project is inspired by another project from Robert Giesecke which has 220,000 downloads on NuGet.
Fun fact: some Python libraries have used this to implement functionality in a mix of C++ and C#.
And finally, thank you Robert Giesecke and Denis Kuzmin, brilliant, brilliant work!
If you don't care if your C++ program (or a portion of it) gets compiled with the /clr, you can use C++/CLI to simply call any .NET code (as long as you add a reference to it).
Try out this article.
Here is a nice tutorial.
The other route is to make your C# code be exposed as COM.
The easiest way is to use COM interop.
You could use a COM callable wrapper around your C# code compiled into a DLL.
From Microsoft: Write a custom .NET Core host to control the .NET runtime from your native code.
IOW: Call C# from from C++ on both Windows and Linux.
There is sample code on GitHub.
This sample code is cross platform, it allows C# code in .NET Core to be called from any C++ application on both Linux and Windows.
In all honesty, this solution seems to be quite complicated compared to the other DllExport answer. The C++ code is doing a lot of heavy lifting to scan for resouces and entry points, etc. One argument for this answer could be that it is cross-platform. However, the other DllExport answer is also cross-platform as well, and a lot simpler to use.
As an alternate approach, you could use Lua to instantiate the CLR objects, execute, and return the results.

Whats the best to call QuantLib methods from C#

I am gonna use QuantLib in C# app (http://quantlib.org/docs.shtml) but I don't trust their .NET conversion project (too immature).
I need only options valuation part.
anyone used it in managed app? whats the best approach?
What I have done in a similar situation is implementing a C++ native dll as an adapter between the C# and C++ projects.
From C# you can access your dll interface with DllImport.
In the dll you can reach the full C++ interface, but it is worth simplifying it to your exact needs on the managed site.
Example:
// in the C++ dll:
extern "C" MY_API void SetInput(double* Values, int Count);
// in C#:
[DllImport("MyStuff.dll")]
public extern static void SetInput(double[] Values, int Count);
C# wrappers for the C++ library are already available and are distributed at the QuantLib download page (these are wrappers as suggested by jmihalicza, not the ongoing C# port you're referring to in your question). The distribution also contains an example of option valuation (look under the CSharp/examples folder).

How to share a class in a Visual C++ DLL with C#?

I wrote my program in C++ and exported it as a DLL. I have a C# WPF GUI and I want to import the DLL to do the processing.
I am very new to C#. How can I use the C++ class in C#? I know I can't just use the .h file.
Because I used pointers in C++, in C# I couldn't use pointers. That's why I got confused. Like in C++ i used char* instead of string, and I need to return double* for a big collection of double data, and things like that.
There are a number of ways:
Export the DLL functions and use DllImportAttribute to P/Invoke into the DLL.
If it is a COM DLL, then you can generate a Runtime Callable Wrapper via TLBIMP.exe
You can use C++/CLI to build create a .Net assembly which loads and calls methods on the DLL natively.
To address your additional concerns, yes, you can use pointers in C#. If you have a function which has a double* parameter, you can declare that in C# like this:
[DllImport("Your.DLL")]
private static extern unsafe void DoProcessing(double* data, int dataSize);
You need to make sure you check the "Allow Unsafe Code" checkbox on the build tab of the C# project, and after that, you can use pointers to your heart's content.
However, note that while I'm providing the pointer signature here, since you are obviously comfortable with pointers, there are other signatures which could be more safe for you to use, and would not require you to compile C# with unsafe code. The standard marshaller in the CLR will take care of the conversion from a pointer to a C# array, provided you give it a bit of a hint if the length is required:
[DllImport("Your.DLL")]
private static extern void DoProcessing(
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] double[] data,
int dataSize);
This instructs the marshaller to use the parameter at index 1 (the 2nd parameter) as the size of the array of doubles pointed at by the 1st parameter. This allows you to avoid pointers in C#, and use safe CLI types. However, if you like pointers, my advice is to just use them - the C# will be easier for you than having to figure out how to write the method signature without them.
For more details on P/Invoke, refer to this documentation: http://msdn.microsoft.com/en-us/library/aa288468(VS.71).aspx
A lot depends on the structure of your C++ dll. If you have just a handful of functions, and they are not member functions of a class, then you can make them "extern C" functions and use the P/Invoke capability in .NET (sometimes called DllImport because of the attribute you use) to access the functions from C#.

C++ & C#, how to create wrapper dll in C++ for C# to call instance function in C++ dll?

Received an unmanaged C++ dll with instance functions which need to be called from my C#. need to write a wrapper C++ dll to bridge the C# and original C++ dll as suggested by experts here. it is new to me and want to learn from you.
Header file of the original C++ dll likes this:
class EXPORT_MACRO NB_DPSM
{
private:
string sFileNameToAnalyze ;
public:
NB_DPSM(void);
~NB_DPSM(void);
void setFileNameToAnalyze(string FileNameToAnalyze) ;
int WriteGenbenchData(string& message) ;
};
Start from a Class Library project template or CLR Empty Project template?
What's the wrapper code should look like?
Anywhere has step by step example for this?
thanks,
Oops, didn't read the question quite correctly. Check out this article, http://www.codeguru.com/Cpp/Cpp/cpp_managed/interop/article.php/c6867/
1) Need list of functions exported by the dll, which should be available in the header file.
2) Do DllImports for the functions you want to use
3) Marshal in/out parameters appropriately
This link should explain in more detail, http://msdn.microsoft.com/en-us/library/aa288468(VS.71).aspx

Categories