Can you call a C# DLL from a C DLL?
The most straight forward way of doing this is to expose one of the C# classes in your C# DLL as a COM object, and then create an instance of it from your C/C++ DLL. If that isn't an acceptable option, you'd need to create a mixed-mode C++ DLL (which contains both managed and unmanaged code). Your C/C++ DLL can call exported functions in your mixed-mode DLL, which can in turn forward the calls on to your C# class.
Call function from DLL?
Add the DLL via the solution explorer - right click on references --> add reference then "Browse" to your DLL - then it should be available.
Using C dll in C#
You can use PInvoke
Platform Invocation Services (PInvoke)
allows managed code to call unmanaged
functions that are implemented in a
DLL.
Here is a great tutorial by the NAG (Numerical Algorithms Group) group
Call C# dll function from C++/CLI
You must be using c++ CLI, otherwise you could not call DllImport.
If that is the case you can just reference the c# dll.
In c++ CLI you can just do as follows:
using namespace Your::Namespace::Here;
#using <YourDll.dll>
YourManagedClass^ pInstance = gcnew YourManagedClass();
where 'YourManagedClass' is defined in the c# project with output assembly 'YourDll.dll'.
** EDIT **
Added your example.
This is how your example needs to look like in CLI (for clarity I am assuming that G
etResult is not a static function, otherwise you would just call Calculate::GetResult(...)
private: System::Void CalculateResult(int arg1, int arg2)
{
int rez=0;
//Call C++ function from dll
Calculate^ calculate= gcnew Calculate();
rez=calculate->GetResult(arg1,arg2);
}
Calling C# from C
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)
Call a C# method/function from a C++ DLL (which is loaded from C# with Dllimport)
So ok, after a few test on starting back to zero, I finally managed to get this callback running !
So here is the test project I created to use the callback.
On C++ side
export.def
LIBRARY TestCallBack
EXPORTS
callCSharpFunction
TestCallBack.cpp
__declspec(dllexport) void callCSharpFunction ( void *fctPointer(int) )
{
fctPointer(123456);
}
This C++ project is being built as a "DLL" file and put within a "lib" project in the C#'s project folder.
On C# side
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace ConsoleApplication1
{
class Program
{
// Set the library path
const string dllFilePath =
"C:\\PathToProject\\TestCallBack\\ConsoleApp\\lib\\TestCallBack.dll";
// This is the delegate type that we use to marshal
// a function pointer for C to use. You usually need
// to specify the calling convention so it matches the
// convention of your C library. The signature of this
// delegate must match the signature of the C function
// pointer we want to use.
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate void FunctionPointer( int nb);
// This is the function we import from the C library.
//[DllImport(dllFilePath)]
[DllImport(dllFilePath, CallingConvention = CallingConvention.Cdecl)]
public static extern void callCSharpFunction(IntPtr fctPointer);
// This is the placeholder for the function pointer
// we create using Marshal.GetFunctionPointerForDelegate
static IntPtr FctPtr;
// This is the instance of the delegate to which our function
// pointer will point.
FunctionPointer MyFunctionPointer;
// This calls the specified delegate using the C library.
void CallFunctionPointer(FunctionPointer cb)
{
// make sure the delegate isn't null
if (null == cb) throw new ArgumentNullException("cb");
// set our delegate place holder equal to the specified delegate
MyFunctionPointer = cb;
// Get a pointer to the delegate that can be passed to the C lib
FctPtr = Marshal.GetFunctionPointerForDelegate(MyFunctionPointer);
// call the imported function with that function pointer.
callCSharpFunction(FctPtr);
}
static void Main(string[] args)
{
// This is the instance of the delegate to which our function
// pointer will point.
FunctionPointer printInConsoleDelegate;
// Create the delegate object "MyFunctionPointer" that references
printInConsoleDelegate = new FunctionPointer(printInConsole);
// Get a pointer to the delegate that can be passed to the C lib
IntPtr printInConsolePtr =
Marshal.GetFunctionPointerForDelegate(printInConsoleDelegate);
Console.WriteLine(
"Call C++ which's calling back C# func \"printInConsole\"");
// Call C++ which calls C#
callCSharpFunction(printInConsolePtr);
// Stop the console until user's pressing Enter
Console.ReadLine();
}
public static void printInConsole(int nb)
{
// Write the parameter in the console
Console.WriteLine("value = " + nb + "; ");
}
}
}
Related Topics
How to Ask The Socket to Wait for More Data to Come
How to Inject JavaScript in The Wp7 Webbrowser Control
Visual Studio C# Intellisense Not Automatically Displaying
Getting Selected Value of a Combobox
How Does Wpf Inotifypropertychanged Work
How to Check If a Given Value Is a Generic List
Fill an Array (Or Arraylist) from SQLdatareader
How to Render Encoded Tags as Proper HTML, Rather Than Text
Taskscheduler.Unobservedtaskexception Event Handler Never Being Triggered
Logoff Interactive Users in Windows from a Service
How to Get Error Information When Httpwebrequest.Getresponse() Fails
How to Share Sessions Between PHP and ASP.NET Application
File Exists by File Name Pattern
Embedding Flash Player in a C++ or Java Application
Attach Debugger to Iis Instance