3

I have a library provided, which i know uses C++. I imported the DLL as such:
[DllImport("pst")] private static extern int pst_get_sensor(ref PSTSensor sensor); The PSTSensor is a struct, in a C++ example it was defined as such:

struct PSTSensor
{
        char    name[80];       /**< Device name */
        int     id;             /**< Device identifier (for other tracking interfaces */
        float   pose[16];       /**< Device pose estimate as row-major matrix */
        double  timestamp;      /**< Time the data was recorded */
};

The problem is, that besides an Int and a Double, it uses a Float, and more importantly an array. An array is something way different between C# and C++. When using this struct to call pst_get_sensor(ref sensor); the entire development environment crashes on me when running the code.

I currently do my struct in C# like this:

struct PSTSensor{
        public char[] name;
        public int id;
        public float[] pose;
        public double timestamp;
    }

My question is, how do i create an array that C++ understands, and properly returns? Is this even possible?

Thanks a lot in advance, Smiley

2 Answers 2

6

Your C# struct needs to define the inline array lengths. And the name field is best declared as a string in the C# code. That makes it much easier for you to work with it.

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
struct PSTSensor
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
    public string name;
    public int id;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
    public float[] pose;
    public double timestamp;
}

The struct layout attribute is optional here, because it just re-states default values. But you may choose to keep it in order to be explicit about your intent.

Sign up to request clarification or add additional context in comments.

3 Comments

Ok, let me try this out. In the mean time. I probably will need to read up on what marchalling is, and what unmanagedTypes are (i do not code in C++ yet, so that makes this so much harder to understand)
This MSDN topic will help: msdn.microsoft.com/en-us/library/…
It works, awesome! i decided to keep the optional line for future reference. Thanks a million, 3 teachers could not get me my answer, and i saw marshaling in other context, but i did not get what it does or how to implement it. Thanks!
1

You can use fixed keyword with allowing unsafe code option in properties

unsafe struct PSTSensor
{
    public fixed char name[80];
    public int id;
    public fixed float pose[16];
    public double timestamp;
}

This will be the declaration and for using passing it to cpp function you can call like this

unsafe 
{
   PSTSensor stSensor = new PSTSensor();
   testfunc(stSensor); //function call cpp
}

3 Comments

But now your struct is much more onerous to use and you are compelled to use unsafe code. Yes you can do this, but you should not.
i agree for unsafe ,but how is it more onerous?
Ask yourself how you read and write the fixed arrays? And then compare with the variant that does not use unsafe code. Finally, not that char is two bytes wide in C#. So you'd need to use fixed byte name[80] and how would you access that?

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.