koopaking3
koopaking3

Reputation: 3433

How to PInvoke in C# an array of structs inside another struct

From C#.NET I'm trying to PInvoke a method from a C++ assembly (no access to source) with this signature

result_code get_values(values_report_type *values_report)

Where values_report is a pointer to a struct of values_report_type containing the values I am querying which are returned by the method. The struct looks like this:

typedef struct{
    int countOfValues;
    values_type* values;
    const char* name;
} values_report_type;

Where values is an array of struct values_type.

Here's what I would assume to be the problem: the C++ assembly I am working against gives me no information about the content of the values_type struct other than the definition

typedef struct values_type_struct *values_type

According to documentation this privacy is intentional.

So, my C# PInvoke looks like this right now:

[DllImport("MyLibrary.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
internal static extern result_code get_values(out values_report_type values_report);

internal struct values_report_type{
    int countOfValues;
    IntPtr values;
    string name;
}

That works fine and gives me a pointer to the values struct, but what I need is to access the array of values_type structs and get a pointer to each of the items in the array (a pointer to each item is all I need since I don't have a definition for the struct contents). But I can't think of a way to achieve this, especially because the library has limited me in what it says about that struct (not even giving length). In C++ it would just be something like values_report.values[0] and so on for each item as defined by countOfValues, but I don't know of a way to make it work when marshalling it to .NET.

Is there a way to solve this in C# via marshalling?

Upvotes: 1

Views: 817

Answers (1)

David Heffernan
David Heffernan

Reputation: 612884

values is not an array of struct. It is an array of pointers to struct.

Based on the comments, and looking at the code, it seems that you don't have a definition of the struct itself. This is what is known as an opaque pointer. You don't need to know the struct size, you just deal in the pointer to the struct, passing that back to the library.

Read the opaque pointer values from the array like this:

IntPtr Value = Marshal.ReadIntPtr(values_report.values, i*IntPtr.Size);

This obtains the ith value.

Upvotes: 2

Related Questions