Is it possible to call a method in c# from c++ DLL ?
I have good communication c# -> C++ , but I would like to be able to initiate a call C++ -> c# to poll some data
my code looks something like this...
host.h
/*
define the exporter for the C API
*/
#ifdef DLL_EXPORT
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT __declspec(dllimport)
#endif
class myClass
{
public:
myCLass(){
//do some initialising
}
~myCLass(){
//do some tidying
}
int getInt(int target) {
switch (target)
{
case 0:
return someIntValue;
case 1:
return someOtherIntValue;
default:
return 0;
}
}
std::string getString(int target) {
switch (target)
{
case 0:
return someStringValue;
case 1:
return someOtherStringValue;
default:
return "";
}
}
}
extern "C" {
DLL_EXPORT myClass* myClassConstructor();
DLL_EXPORT void DestroySpatialser(const myClass* _pContext);
DLL_EXPORT int getInt(myClass* _pContext, int target);
DLL_EXPORT void getString(myClass* _pContext, int target, __out BSTR* returnStr);
}
host.cpp
extern "C" {
myClass* myClassConstructor()
{
return new myClass();
}
void myClassDestructor(const myClass* _pContext)
{
if (_pContext != nullptr)
{
_pContext->~myClass();
delete _pContext;
}
}
//example
int getInt(myClass* _pContext, int target)
{
if (_pContext == nullptr)
{
return K_ERR_INT;
}
return _pContext->getInt(target);
}
void getString(myClass* _pContext, int target, __out BSTR* returnStr)
{
std::string str;
if (_pContext == nullptr)
{
str = K_ERR_CHAR;
}
else {
str = _pContext->getString(target);
}
const std::string stdStr = str;
_bstr_t bstrStr = stdStr.c_str();
*returnStr = bstrStr.copy();
}
}
csharp.cs
private const string dllname = "myhost";
[DllImport(dllname)]
private static extern IntPtr myClassConstructor();
[DllImport(dllname)]
private static extern void myClassDestructor(IntPtr _pContext);
[DllImport(dllname)]
private static extern int getInt(IntPtr _pContext, int target);
[DllImport(dllname)]
private static extern float getFloat(IntPtr _pContext, int target);
[DllImport(dllname, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
extern static void getString(IntPtr _pContext, int target, [MarshalAs(UnmanagedType.BStr)] out String str);
private static IntPtr _pContext;
public static IntPtr Create()
{
_pContext = myClassConstructor();
Debug.Log("_pContextcreated");
return _pContext;
}
public static void Destroy()
{
myClassDestructor(_pContext );
}
private static int _getInt(int target)
{
return getInt(_pContext , target);
}
private static string _getString(int target)
{
String str;
getString(_pContext , target, out str);
return str;
}
This all works fine.
I'd like to add the ability to get a value from the .cs app (it will be a struct of 3 floats) which should be called from the instance of myClass.
I don't want to initiate this on c# side (i know how to do that).
Any advice?
EDIT
I implemented the solution found here https://forum.unity.com/threads/communicating-c-with-c.89930/#post-586885
with two changes (see comments below for why)
public int whatever = 0;
public delegate int myCallbackDelegate( int n, int m );
private myCallbackDelegate myCallback; // <-- add this line
[DllImport ("DLLImport_CProj")]
private static extern int TakesCallback( myCallbackDelegate fp, int n, int m );
void Awake()
{
myCallback = new myCallbackDelegate( this.myCallback ) // <-- add this
int resp = TakesCallback(myCallback, 10, 20 ); // <-- change to this
Debug.Log( resp );
}