0

I am working on mixed application, using both managed & native codes I want to call a function deployed in a native class from Main() function located in Program.cpp which is managed class.

i tried using std::thread but failed with /cli

i tried to use Managed System::Threading::Thread but failed because i need to call a native function in a native class.

So how i can handle thing without using any third-party?

  • It is formally *verboten*, managed code is not guaranteed to run on an OS thread. You'll have to doctor your .h file so the std::thread member is not visible to the C++/CLI compiler. Consider an interface or Pimpl. – Hans Passant May 08 '18 at 11:39
  • But i am working on API that's it shall be native, and my app class is all in managed, so i tried with interface but compiler rejected including ... – Abdel Moumen Abdel Raouf May 08 '18 at 11:45
  • When your .h file no longer contains std::thread then you don't have to #include that file either. And be sure that native code gets compiled *without* /clr in effect, a static library project make it easy to partition the code. – Hans Passant May 08 '18 at 11:52
  • So there is no solution for current case with current situation ? – Abdel Moumen Abdel Raouf May 08 '18 at 11:59

1 Answers1

1

If you start from a native project you need to do the following steps:

  • Select project properties and change the option "No Common Language Runtime Support" to "Common Language Runtime Support /clr".
  • Open the "Property Manager" from "View" menu / "Other Windows" and add the property sheet "C++ Common Language Runtime Support" to the needed configuration (eg.: Debug | Win32) on my system this sheet is under "C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140". I use the "Microsoft.Cpp.ManagedExtensions.props" file.
    • You need to remove std::thread completely.

headerish:

#pragma once
#include<stddef.h>

using namespace System;
using namespace System::Threading;

namespace FooSpace
{
    // Native stuff 
    public class Native
    {
    public:
        static void Foo() { }
        void Bar() {
        }
    };

    // Managed stuff
    public ref class Managed
    {
    private:
        Native* m_Native;

    public:
        Managed()
        {
            m_Native = new Native();
        }

        ~Managed()
        {
            if (NULL != m_Native)
            {
                delete m_Native;
                m_Native = NULL;
            }
        }

        void Bar()
        {
            m_Native->Bar();
        }

        static void ThreadCall(Object^ o)
        {
            auto me = (Managed^)o;
            me->Bar(); // Call a method of an instance of the native class
            Native::Foo(); // Call a static method of the Native class
        }

        void StartThread()
        {
            auto t = gcnew Thread(gcnew ParameterizedThreadStart(ThreadCall));
            t->Start(this);
            t->Join();
        }
    };
}

soure file:

#include "stdafx.h"
#include "CppCli_Native.h"

using namespace FooSpace;

int main()
{
    Native::Foo(); // call native static method
    auto native = new Native(); // create native instance
    native->Bar(); // call native method

    auto managed = gcnew Managed();
    managed->Bar(); // This will call bar
    managed->StartThread(); // This will start a thread
    delete managed;

    Console::ReadLine();
    return 0;

}

Edit: It turns out that you don't need to use IntPtr to store native class.

I find this answer also useful, it also gives us a fast introduction to c++-cli syntax.

minus one
  • 642
  • 1
  • 7
  • 28