I have a structure in a C library:
#pragma pack(push, packing)
#pragma pack(1)
typedef struct
{
unsigned int ipAddress;
unsigned char aMacAddress[6];
unsigned int nodeId;
} tStructToMarshall;
__declspec(dllexport) int SetCommunicationParameters(tStructToMarshall parameters);
This code is compiled with cl /LD /Zi Communication.c
to produce a DLL and PDB file for debugging.
To use this code from a .Net app, I used the P/Invoke Interop Assistant to generate C# code for a wrapper DLL:
This results in the displayed C# wrapper, which I modified to use the correct DLL instead of "<unkown>"
. Also, I do actually want an array of bytes for aMacAddress
, not a string (though I understand how this would usually be helpful):
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, CharSet = System.Runtime.InteropServices.CharSet.Ansi)]
public struct tStructToMarshall
{
/// unsigned int
public uint ipAddress;
/// unsigned char[6]
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = 6)]
public byte[] aMacAddress;
// ^^^^^^ Was "string"
/// unsigned int
public uint nodeId;
}
public partial class NativeMethods
{
internal const string DllName = "lib/Communication.dll";
/// Return Type: int
///parameters: tStructToMarshall->Anonymous_75c92899_b50d_4bea_a217_a69989a8d651
[System.Runtime.InteropServices.DllImportAttribute(DllName, EntryPoint = "SetCommunicationParameters")]
// ^^^^^^^ Was "<unknown>"
public static extern int SetCommunicationParameters(tStructToMarshall parameters);
}
I have two problems: 1. When I set the values of the structure to something nonzero and look up the node ID, it is mangled or corrupted. The IP address and MAC address are fine, but any structure members (including other data types) after an array are broken, showing very large numbers in the C output even if I specified single-digit values. 2. When I call the method, I get an error that says:
A call to PInvoke function '' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.
Attempting to call methods that do not take parameters does not generate this exception. And I'm pretty sure that it matches the target signature, because that's how I generated it!
How can I fix these issues?