Reputation: 379
I have the following structure in my cpp file:
struct EntityData
{
char globalId[512];
int mySpeed;
double x;
double y;
double z;
double h;
double p;
double r;
};
I have a method that gets an index # and returns the correct structure:
extern "C" { __declspec(dllexport) getDataStruct(int index)
this method is exposed so I can use this method in my c# application and I keep getting an error:
marshal directive exception.
my c# code:
[DllImport("my64.dll")]
[return: MarshalAs(UnmanagedType.LPStruct)]
public static extern EntityDataRx getDataStruct(int index);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct EntityDataRx
{
[MarshalAs(UnmanagedType.LPStr, SizeConst = 512)]
StringBuilder globalId;
int mySpeed;
double x;
double y;
double z;
double h;
double p;
double r;
}
What am I missing?
Upvotes: 0
Views: 114
Reputation: 379
Finally Solved. The issue was that from the cpp structure I return a pointer to the structure:
struct EntityData
{
char globalId[512];
int mySpeed;
double x;
double y;
double z;
double h;
double p;
double r;
};
and in my c# application:
[DllImport("listenHLA1516e_64.dll")]
//[return: MarshalAs(UnmanagedType.Struct)] **cancelled not necessary**
public static extern IntPtr getDataStruct(int index);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct EntityDataRx
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
char[] globalId;
int mySpeed;
double x;
double y;
double z;
double h;
double p;
double r;
}
IntPtr a = getDataStruct(i);
EntityDataRx ent = (EntityDataRx)Marshal.PtrToStructure(a, typeof(EntityDataRx));
Upvotes: 0
Reputation: 5920
From the msdn documentation page it says :
The
ByValTStr
type is used for inline, fixed-length character arrays that appear within a structure. Other types apply to string references contained within structures that contain pointers to strings.
So judging by your structure
struct EntityData
{
char globalId[512];
// ...
}
You should define your C# structure like such :
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct EntityDataRx
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 512)]
char[] globalId;
// ...
}
LPStr
is used when you have "a pointer to a null-terminated array of ANSI characters" but what you have instead is a fixed length array.
Upvotes: 4