Call (C#) .NET Core method from C++ - c#

I have 2 components:
- .Net Core Application running on Ubuntu OS.
- C++ shared library (.so)
Now I want C++ component to be able to call .Net Core method, either passing interface to C++ component which will use this interface to callback method implementation or passing method as a parameter to C++ component.
High-level example what I am trying to achieve:
C# component :
public interface IDevice
{
void OnDataAvailable(string data);
}
public class Device: IDevice
{
[DllImport("sampleCPPLibrary.so")]
private static extern int SetReceiver(IDevice receiver);
public void OnDataAvailable(string data)
{
Console.WriteLine(data);
}
public void Initialize()
{
SetReceiver(IDevice(this))
}
}
C++ component:
extern "C" {
void SetReceiver(IReceiver * receiver)
{
receiver->OnDataAvailable(10);
}
}
Basically, what I am trying to do is just to pass some kind of "callback" to C++ component and call this "callback" when some event occurs in C++ component.

See See this issue from comments I constructed code where C# calls C and gives it callback delegate. Thus from C then it calls C#, and passes additional int type argument. See comments here from endurox project, and attached c-callback.tar.gz for working example.

Related

C++ function trigger C# function

Basically my code is looks like below
Managed.dll
Managed.cs
class MyManagedClass
{
public ShowMessage()
{
System.out.println("My Message");
}
}
Wrapper.dll
ref class Wrapper
{
};
Native.lib
class NativeClass
{
public:
void NativeMessage()
{
cout<<"Print Message";
}
}
Main
void main
{
NativeClass ob;
ob.NativeMessage();
}
my issue is whenever the "ob.NativeMessage();" called, somehow MyManagedClass::ShowMessage() has to be triggered.
And more impotent Native.lib linked in Wrapper.dll and Wrapper.dll referenced in Managed.dll.
Can any one help me on this.
If you're running strictly from a C++ environment, you will want to host a .NET runtime in your C++ application. If you're running from a .NET environment, that part is already done and you will need to pass a delegate to the C++ code to be called later (this, by the way, is fraught with problems as the .NET runtime up to at least version 3.0 can and will garbage collect delegates out from under you).

WinRT C++/CX to C# multithread marshaling

So we are working on new app for Windows Store and we're utilizing DirectX on C++/CX part of app and C# on other. As we needed some sort of communication, we created interface in shared library (C#) and class that implements it on C# side of the project. We then pass instance of that class to the C++. When C++ need to communicate with c#, it calls methods from shared interface and c# executes what was implemented in the class.
The problem arises when C++ calls methods from another thread than then object was passed on to it. Error:
The application called an interface that was marshalled for a different thread.
Here's how it works:
C# instance of shared interface (some class)
C# -> C++ \/ passed in parameter of public C++ method
C++ saves to variable
C++ creates new thread
C++ calls instance->SayHello();
C# exception
Shared interface: (C#)
public interface IUserMessageService
{
void WriteMessage(string message, MessageTypes type);
}
Implementation: (C#)
public sealed class UserMessageService : IUserMessageService
{ ... }
Assign method (C++)
void AssignUserMessageService(...::IUserMessageService ^service) { m_service = service; }
I then call AssignUserMessageService with instance of UserMessageService from UI thread. Error occurs when I try to access data passed by C++ when calling WriteMessage in another thread.
Is there any other way to pass instance or call method?
The problem was that I was using CoreApplication.MainWindow.CoreWindow.Dispatcher instead of Window.Current.Dispatcher

Cannot resolve/understand "overriding virtual function differs only by calling convention"

I currently had a pending question open - however after working on it I ran onto a new problem and the errors that I was getting while attempting to build it were:
Error 1 error C2695: 'MyEventsSink::OnSomethingHappened': overriding virtual function differs from 'Library::IEventsSink::OnSomethingHappened' only by calling convention
Error 2 error C2695: 'MyEventsSink::SomeTest': overriding virtual function differs from 'Library::IEventsSink::SomeTest' only by calling convention
I tried goggling regarding this error but I could not figure it out.
Here is what I am doing , I have a managed C# dll class library which is being consumed by a native C++ application. The code for C# interface is as follows and the implemention of this interface is in C++.
The C# code is
[ComVisible(true), ClassInterface(ClassInterfaceType.None), Guid("fdb9e334-fae4-4ff5-ab16-d874a910ec3c")]
public class IEventsSinkImpl : IEventsSink
{
public void OnSomethingHappened()
{
//Doesnt matter what goes on here - atleast for now
}
public void SomeTest(IEventsSink snk)
{
//When this is called - it will call the C++ code
snk.OnSomethingHappened();
}
}//end method
And its implemetation code in C++ is
class MyEventsSink : public Library::IEventsSink
{
public:
MyEventsSink() {}
~MyEventsSink() {}
virtual HRESULT OnSomethingHappened()
{
std::cout << "Incredible - it worked";
}
virtual HRESULT SomeTest(IEventsSink* snk)
{
//Doesnt matter this wont be called
}
};
Apparently during the build process VS2010 complains of the above mentioned errors. Any suggestions on how I could resolve those errors.
Try using __stdcall calling convention:
virtual HRESULT __stdcall OnSomethingHappened()
Normally, C++ uses the __cdecl calling convention, where the caller removes the parameters from the stack after the call. Most Windows API functions including COM use __stdcall where the callee removes the parameters from the stack.
Obviously, when you override a virtual function, the calling convention of both functions must be the same, because the function call is resolved at runtime.

set C++ function pointer as C# delegate

I have a unmanaged c++ application as COM client and a C# COM server.
now i want COM server can invoke a c++ function.
C# :
[ClassInterface(ClassInterfaceType.AutoDual)]
public class SomeType
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void DeleCallBack(string info);
public DeleCallBack CallBack;
public void SetCallBack(ref IntPtr ptr)
{
CallBack = (DeleCallBack)Marshal.GetDelegateForFunctionPointer(ptr, typeof(DeleCallBack));
}
}
C++:
HRESULT hr = E_FAIL;
CComPtr<WindowsFormsApplicationVC9::_SomeType> spTmp;
hr = spTmp.CoCreateInstance(__uuidof(WindowsFormsApplicationVC9::SomeType));
if (SUCCEEDED(hr))
{
spTmp->SetCallBack(OnCallBack);
}
void OnCallBack(BSTR info)
{
// c++ function call...;
}
I'm not sure it is the right way to just pass the OnCallBack function pointer to SetCallBack.
I noticed that some sample of calling GetDelegateForFunctionPointer should GetProcessAddress to get the function pointer address, but i can't do that since there are may be different c++ COM client with different function name.
any suggestion?
One way to do it is to expose your C++ functions via __declspec(dllexport), then simply write P/Invoke for those functions. Now you can use those P/Invoke functions as delegates.
Deep down this is essentially the GetProcAddress approach but the C# compiler makes it syntactically nicer for you.

Can I export a C++ interface with C-Style methods to a C# dll

I'm trying to avoid COM. I'm designing a mixture C# and C++ controls on a C++ exe.
One method I came up with is PInvoking my C++ exe from C#, and sending windows messages to the C# windows. However the amount of methods I call on the controls base class is too long to justify windows messages.
So, if it's possible to export a whole C# interface to a C++ exe, that would be way easier.
I want to avoid COM because I may have to support windows 2000, and doing COM without relying on the manifest would be a deployment hassle on a software package that currently doesn't set much in the registry.
You could write a C wrapper for each of your C++ controls, and PInvoke from C#.
For example this C++ class:
class Example
{
public:
int MyMethod(int param);
}
and in a extern "C" block in your c++ exe:
void * CreateExample() { return new Example(); }
int Example_MyMethod(void * handle, int param) { reinterpret_cast<Example*>(handle)->MyMethod(param)); }
and in C#:
public class Example
{
private IntPtr handle;
public Example()
{
handle = _CreateExample();
}
public int MyMethod(int param)
{
return _MyMethod(param);
}
[DllImport("yourdll.exe")]
private static extern IntPtr _CreateExample();
[DllImport("yourdll.exe")]
private static extern int _MyMethod(IntPtr handle, int param);
}
I use C++/CLI with VS 2010 to do this. You can expose a DLL C interface that can be consumed in the usual way, the implementation would just marshal data from that interface to your C# assembly.
Related question I think Calling C# from C++, Reverse P/Invoke, Mixed Mode DLLs and C++/CLI

Categories

Resources