1

I'm trying to return from my native c++ code to c# code a struct with field of other struct but have an error : Method's type signature is not PInvoke compatible.

this is my c++ code:

namespace path
{
struct Vector3
{
public:
    float x;
    float y;
    float z;
};

struct PointState
{
public:
    Vector3 position_;
    bool reformation;
};

}

Here my api functions:

extern "C"
{
PATHFINDER_API void SetupGraph(const char * json);
PATHFINDER_API path::Vector3 CheckReturn();
PATHFINDER_API path::PointState CheckStruct();
}

And this is my C# struct code:

 [StructLayout(LayoutKind.Sequential)]
public struct Vector3
{
    public float x;
    public float y;
    public float z;
};

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct PointState
{
    [MarshalAs(UnmanagedType.LPStruct)]
    public Vector3 position_;
    public bool reformation;
};

and Pinvoke DLLImport:

        [DllImport("path", CallingConvention = CallingConvention.Cdecl, ExactSpelling = false, EntryPoint = "CheckStruct")]
    private static extern PointState CheckStruct();

    public PointState CheckReturn2()
    {
        return CheckStruct();
    }

Pls, what i'm doing wrong? I can't find answer by myself.

2
  • Your code is not complete. We can't see the C++ code that declares PointState. Commented Feb 26, 2018 at 11:21
  • Yes, sorry, fixed! Commented Feb 26, 2018 at 11:44

1 Answer 1

2

There are a few problems with your code:

  • You used [MarshalAs(UnmanagedType.LPStruct)] on the nested struct, but that's just wrong. That field isn't a pointer. That attribute should be removed.
  • The bool type can't be marshalled in a return value. You can replace the C# bool with byte to resolve that, and then compare the value against zero.
  • In addition, some of the attributes that you have added seem needless. I suspect that you did the usual thing of trying lots of changes at random, but then leaving them in the code that you posted here.

I'd use the following declarations:

[StructLayout(LayoutKind.Sequential)]
public struct Vector3
{
    public float x;
    public float y;
    public float z;
};

[StructLayout(LayoutKind.Sequential)]
public struct PointState
{
    public Vector3 position_;
    private byte _reformation;
    public bool reformation { get { return _reformation != 0; } }
};

[DllImport("path", CallingConvention = CallingConvention.Cdecl)]
private static extern PointState CheckStruct();
Sign up to request clarification or add additional context in comments.

1 Comment

Omg, thanks a lot! I was think that problem is in struct, and problem was in bool. Yes, you absolutely right, i try all i can, and not clean up.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.