4

I've got a managed c++ class/struct with constructors that take input. In C#, I can only "see" the default constructor. Is there a way to call the other constructors, without leaving managed code? Thanks.

Edit: In fact, none of its functions are visible.

C++:

public class Vector4
{
private:
    Vector4_CPP test ;

    Vector4(Vector4_CPP* value)
    {
        this->test = *value;
    }


public:
    Vector4(Vector4* value)
    {
        test = value->test;
    }
public:
    Vector4(float x, float y, float z, float w)
    {
        test = Vector4_CPP( x, y, z, w ) ;
    }


    Vector4 operator *(Vector4 * b)
    {
        Vector4_CPP r = this->test * &(b->test) ;
        return Vector4( &r ) ;
    }
} ;

C#:

// C# tells me it can't find the constructor.
// Also, none of them are visible in intellisense.
Library.Vector4 a = new Library.Vector4(1, 1, 1, 1);
linuxuser27
  • 7,183
  • 1
  • 26
  • 22
Narf the Mouse
  • 1,541
  • 5
  • 18
  • 30
  • 2
    Class declaration should be `ref class Vector4`. Not sure if that is the precise issue here, but it is an issue. – linuxuser27 Jun 03 '12 at 01:27
  • I'd rather use a struct for a Vector4 than a class. It tends to be faster. – Narf the Mouse Jun 03 '12 at 01:30
  • Okay, that is fine, but that is not what you have. I may be off here, but you are using C++\CLI correct? If that is the case and you want a struct then you need to declare the type as `value struct Vector4` or `ref struct Vector4`. I am not familiar with the syntax you are using if you want to consume a C++\CLI class from C# – linuxuser27 Jun 03 '12 at 01:38
  • I'm trying to get a usable unmanaged SIMD Vector4_CPP in C#. C++ just told me that you can't have unmanaged types in managed code... – Narf the Mouse Jun 03 '12 at 01:40
  • It should tell you that with the current signature. Convert it to one of the signatures previously mentioned. – linuxuser27 Jun 03 '12 at 01:42
  • The problem then is, it doesn't like the unmanaged Vector4_CPP being a member; if I make Vector4_CPP managed, it doesn't like m128 being a member, which kinda negates the point. – Narf the Mouse Jun 03 '12 at 01:44
  • I would recommend making it a ref class, that might be why the constructors aren't visible. You could make the SSE calls in a static function, in another class if necessary. I'm curious if the SSE calls will see a performance gain in C#; I tried that once and got no performance gain when calling SSE functions from C#, I never figured out why. – HypnoToad Jun 03 '12 at 02:00
  • The __m128 needs to be declared as a pointer. What I don't know is if I need to delete the pointer. Better safe than sorry... – Narf the Mouse Jun 03 '12 at 02:20
  • And now it looks like I have to somehow read/write protected memory... – Narf the Mouse Jun 03 '12 at 03:22
  • *Arg!* It's either only memcpy'ing one-half the values in, or one-half the values out. – Narf the Mouse Jun 03 '12 at 04:02
  • Ultimately possible, but due to needing to use "new __m128" to get unmanaged code to work nicely with managed, it's much slower. No solution yet. – Narf the Mouse Jun 03 '12 at 05:39
  • 1
    Well, anyway, the original question has been answered, so mark the answer down so I can mark it as answered and you can get upvotes. :) – Narf the Mouse Jun 03 '12 at 15:36

1 Answers1

2

The first problem is that your class declaration is for a unmanaged C++ object.

If you want a managed C++/CLI object, then you need one of the following:

public value struct Vector4

or

public ref class Vector4

Also, any C++/CLI function signature that includes native types will not be visible to C#. So any parameters or return values must be either your C++/CLI managed types or .NET types. I'm not sure how the operator* signature would look, but you could make rest like this:

public value struct Vector4 
{   
  private:
    Vector4_CPP test;

    Vector4(Vector4_CPP* value)
    {
        this->test = *value;
    }

  public:
    Vector4(Vector4 value)
    {
        test = value.test;
    }

    Vector4(System::Single x, System::Single y, System::Single z, System::Single w)
    {
        test = Vector4_CPP( x, y, z, w ) ;
    } 
}

Or:

public ref class Vector4 
{   
  private:
    Vector4_CPP test;

    Vector4(Vector4_CPP* value)
    {
        this->test = *value;
    }

  public:
    Vector4(Vector4^ value)
    {
        test = value->test;
    }

    Vector4(System::Single x, System::Single y, System::Single z, System::Single w)
    {
        test = Vector4_CPP( x, y, z, w ) ;
    } 
}
17 of 26
  • 27,121
  • 13
  • 66
  • 85
  • Value structs cannot have constructors (or other "special" member functions), I don't think the first example will compile. – Breakthrough Jun 09 '18 at 22:56