1

I want to call c# delegate from c++ code in my cocos2d-x 3.3 game (wp8-xaml backend). I found this: http://discuss.cocos2d-x.org/t/wp8-cocos2dx-and-xaml/4886/6

And here's my class "NativeEventHelper.cpp" in c++ project:

#pragma once
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
namespace PhoneDirect3DXamlAppComponent
{
public delegate void CallNativeFunctionDelegate();
public ref class NativeEventHelper sealed
{
public:
    NativeEventHelper(void);
    void SetCallNativeFunctionDelegate(CallNativeFunctionDelegate^ delegate) {
        m_CallNativeFunctionDelegate = delegate;
    }

    bool NativeEventHelper::CallNativeFunction()
    {
        if (m_CallNativeFunctionDelegate)
        {
            m_CallNativeFunctionDelegate->Invoke();
            return true;
        }
        return false;
    }

private:
    property static CallNativeFunctionDelegate^ m_CallNativeFunctionDelegate;
};

}
#endif

Here's my callback in c# (MainPage.xaml.cs) class:

 public void CallNativeFunction()
    {
        Dispatcher.BeginInvoke(() =>
        {
            Debug.WriteLine("# NATIVE CODE #");
        });
        return;
    }

And here's an issue. In constructor I have to create new NativeEventHelper (from c++ class), but I don't know how to add refence, because compiler is complaining about unknown identifier "NativeEventHelper".

 NativeEventHelper helper = new NativeEventHelper();
 helper.SetCallNativeFunctionDelegate(CallNativeFunction);

I also found this: Calling C# method from C++ code in WP8

This seems to be exactly the same, but again I don't know how to reference this class. This is not working in my case: https://software.intel.com/en-us/articles/using-winrt-apis-from-desktop-applications Instead of windows I see windows phone sdk in references and cannot add winrt.

Community
  • 1
  • 1
Makalele
  • 7,431
  • 5
  • 54
  • 81
  • Are you using the `PhoneDirect3DXamlAppComponent` namespace? – Peter Torr - MSFT Feb 08 '15 at 07:53
  • Yes, I tried that, but it's complaining that it cannot find such namespace. – Makalele Feb 08 '15 at 11:05
  • Did you add a reference from the C# project to the C++ project? – Peter Torr - MSFT Feb 08 '15 at 17:32
  • I've got all projects in one solution so I shoudn't need nothing more. – Makalele Feb 08 '15 at 21:05
  • You still need to create project-to-project references. Right-click the C# project, choose Add -> Reference, then make sure the C++ project is referenced. – Peter Torr - MSFT Feb 09 '15 at 03:44
  • As I've checked it's already referenced. The exact error is: Error 3 error LNK2019: unresolved external symbol "public: __cdecl PhoneDirect3DXamlAppComponent::NativeEventHelper::NativeEventHelper(void)" (??0NativeEventHelper@PhoneDirect3DXamlAppComponent@@Q$AAA@XZ) referenced in function "public: virtual class Platform::Object ^ __cdecl PhoneDirect3DXamlAppComponent::__NativeEventHelperActivationFactory::[Platform::Details::IActivationFactory]::ActivateInstance(void)" (?ActivateInstance@? – Makalele Feb 09 '15 at 11:53
  • You don't define your constructor above; is it implemented in the cpp file? – Peter Torr - MSFT Feb 09 '15 at 16:17
  • It's defined in cpp file like this: NativeEventHelper(void); this code should be working so I didn't add anything to cpp file. – Makalele Feb 09 '15 at 16:19
  • I assume you mean "defined in header" -- that just tells the **compiler** "hey I'm going to have a method called bla" but it doesn't actually create such a method. Then the **linker** will look for the implementation and discover none exists. If you don't actually need the constructor then just delete it. The compiler will create one for you. – Peter Torr - MSFT Feb 09 '15 at 20:46
  • Well I'm not winrt expert. This script should work without any changes. After commeting out contructor I'm getting this: Error 4 The .winmd file 'cocos2d.winmd' contains type 'PhoneDirect3DXamlAppComponent.__INativeEventHelperPublicNonVirtuals' outside its root namespace 'cocos2d'. Make sure that all public types appear under a common root namespace that matches the output file name. CocosProject I've changed namespace name to cocos2d so it's not complaining, but now c++ doesn't see this class and I don't know how to invoke this method from it. – Makalele Feb 10 '15 at 08:22

1 Answers1

1

I finally solved it!!

First of all: I had to change namespace to cocos2d. Also I had to ignore warnings and just make full clean and rebuild. After that it works. To call code in c++ I figured out this:

NativeEventHelper^ nativeEventHelper = ref new NativeEventHelper();
nativeEventHelper->CallNativeFunction();

Fixed NativeEventHelper.cpp file:

#pragma once
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
namespace cocos2d
{
    public delegate void CallNativeFunctionDelegate();
    public ref class NativeEventHelper sealed
    {
    public:
        NativeEventHelper(void);
        void SetCallNativeFunctionDelegate(CallNativeFunctionDelegate^ delegate) {
            m_CallNativeFunctionDelegate = delegate;
        }

        bool NativeEventHelper::CallNativeFunction()
        {
            if (m_CallNativeFunctionDelegate)
            {
                m_CallNativeFunctionDelegate->Invoke();
                return true;
            }
            return false;
        }

    private:
        property static CallNativeFunctionDelegate^ m_CallNativeFunctionDelegate;
    };

}
#endif
Makalele
  • 7,431
  • 5
  • 54
  • 81