Note that there are some explanatory texts on larger screens.

plurals
  1. POUnmarshalling a Struct containing an array of structs
    primarykey
    data
    text
    <p>I'm trying to get back this struct from a native C library through P/Invoke: </p> <pre><code>struct ndb_mgm_cluster_state { int no_of_nodes; struct ndb_mgm_node_state node_states[1]; }; </code></pre> <p>where <code>ndb_mgm_node_state</code> is:</p> <pre><code>struct ndb_mgm_node_state { int node_id; enum ndb_mgm_node_type node_type; enum ndb_mgm_node_status node_status; int start_phase; int dynamic_id; int node_group; int version; int connect_count; char connect_address[sizeof("000.000.000.000")+1 ]; int mysql_version; }; </code></pre> <p>The method's signature is:</p> <pre><code> ndb_mgm_cluster_state* WINAPI wrap_ndb_mgm_get_status(HANDLE handle); </code></pre> <p>All of this is provided by a 3rd party library, so nothing can be changed. In C# i have the follow definitions:</p> <pre><code>[DllImport("Ndb_CWrapper.dll", CharSet = CharSet.Ansi)] private static extern IntPtr wrap_ndb_mgm_get_status(IntPtr handle); </code></pre> <p>the structures are:</p> <pre><code>[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct ndb_mgm_cluster_state { public int no_of_nodes; public IntPtr node_states; }; [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct ndb_mgm_node_state { public int node_id; public ndb_mgm_node_type node_type; public ndb_mgm_node_status node_status; public int start_phase; public int dynamic_id; public int node_group; public int version; public int connect_count; [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 17)] public string connect_address; public int mysql_version; }; </code></pre> <p>I tried to unmarshal the results without success (i recieve an oddly error (not an Exception) Fatal error execution, can be a CLR bug or a miscall P/invoke.</p> <p>Obviously the reason is a problem in my P/Invoke call</p> <p>I tried in this way: First of all i unmarshalled the <code>ndb_mgm_cluster_state</code> structure:</p> <pre><code>var res=(ndb_mgm_cluster_state)Marshal.PtrToStructure( tmpPtr, typeof(ndb_mgm_cluster_state)); </code></pre> <p>where <code>IntPtr</code> is the result of the native call. Up to this step everything "seems" to be done right, but when i try to unmarshall the <code>node_states</code> i get the error:</p> <pre><code>ndb_mgm_node_state tmpNode = (ndb_mgm_node_state)Marshal.PtrToStructure( status.node_states, typeof(ndb_mgm_node_state)); </code></pre> <p>What can be the problem? I supposed is something related to the strange declaration of <code>ndb_mgm_cluster_state</code> because is defined an array of 1 element, but it contain several elements. (the number of elements is in <code>no_of_nodes</code>)</p> <p><strong>WORKAROUND:</strong></p> <p>The only way to let everything work i found is to change a bit the signature, in this way:</p> <pre><code>ndb_mgm_node_state* WINAPI wrap_ndb_mgm_get_status(HANDLE handle,int* length); </code></pre> <p>in C#:</p> <pre><code>[DllImport("Ndb_CWrapper.dll", CharSet = CharSet.Ansi)] private static extern IntPtr wrap_ndb_mgm_get_status(IntPtr handle,out int length); </code></pre> <p>where length contains <code>no_of_nodes</code></p> <p>the unmarshall will be in this way:</p> <pre><code>IntPtr tmpPtr = wrap_ndb_mgm_get_status(raw,out length); ndb_mgm_cluster_state tmpRes = new ndb_mgm_cluster_state(); tmpRes.no_of_nodes = length; tmpRes.node_states = new ndb_mgm_node_state[length]; int step=0; for (int i = 0; i &lt; tmpRes.no_of_nodes; i++) { tmpRes.node_states[i] = (ndb_mgm_node_state)Marshal.PtrToStructure( tmpPtr+(step*i), typeof(ndb_mgm_node_state)); step = Marshal.SizeOf(tmpRes.node_states[i]); } </code></pre> <p>I know the step calculation is odd at the monent, but its not that the point. there is no way to let the thing work returning directly the <code>ndb_mgm_cluster_state</code> struct instead of do all of this?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload