0

I want to send an object class or struct callback from C++ to C#,
I send an int or string successfully but failed to send back a class. please help.

Reference:Callbacks from C++ back to C#

Code: C++ pi.h


namespace Cpp {

    class Box
    {
    public:
        double length;   // 长度
        double breadth;  // 宽度
        double height;   // 高度
    };

    typedef void(__stdcall *ComputeCallback)(Box);

    class PI {
    public:
        static double DLL_MACRO compute(ComputeCallback callback);
    };
}

C++ pi.cpp

#include "pch.h"
#include "pi.h"
// pi.cpp: 
#include <cmath>

double Cpp::PI::compute(Cpp::ComputeCallback callback) {
    //System::String^ myString2 = "jumped over the lazy dog.";
    Box Box1; 
    Box1.height = 5.0;
    Box1.length = 6.0;
    Box1.breadth = 7.0;

    callback(Box1);
    return 0;
}

C++ bridge file piCLI.cpp

#pragma once
#include "pi.h"

using namespace System;

//bridge file
namespace ClassLibrary2 {
    public delegate void ComputeDelegate(Cpp::Box);

    public ref class PI abstract sealed {
    public:
        static double compute(ComputeDelegate^ callback) {
            using System::IntPtr;
            using System::Runtime::InteropServices::Marshal;

            IntPtr cbPtr = Marshal::GetFunctionPointerForDelegate(callback);
            return Cpp::PI::compute(
                static_cast<Cpp::ComputeCallback>(cbPtr.ToPointer())
            );
        }
    };
}

C#

using ClassLibrary2;

namespace CallbackWpf
{  
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            Trace.WriteLine("______ start");

            ClassLibrary2.PI.compute(
                Box1 => Trace.WriteLine(Box1));
        }
    }
}

Error:

System.TypeAccessException: 'Attempt by method 'CallbackWpf.MainWindow+<>c.<.ctor>b__0_0(Cpp.Box)' to access type 'Cpp.Box' failed.'

Mike Yang
  • 2,581
  • 3
  • 24
  • 27
  • Where does `Box1` in WPF come from? – nvoigt Mar 14 '20 at 07:05
  • box1 is from C++, C++ code is packed as a DLL and c# load the file – Mike Yang Mar 14 '20 at 08:27
  • You can't access a native type from C#. You could create a C++ managed class that wraps te native type (copies all it's properties etc) and return that instead. – sipsorcery Mar 14 '20 at 08:38
  • Thank you! can you give me an example to study? – Mike Yang Mar 14 '20 at 08:53
  • 1
    public value struct ManagedBox { ... }; is required in the C++/CLI project to make the data accessible to a C# program. The callback must be to a member function of PI so it can copy Box members to a ManagedBox, then invoke the delegate. compute() should not be static. – Hans Passant Mar 14 '20 at 10:55

0 Answers0