将 C++ 结构传递给 C# 应用程序
passing a c++ struct to a c# application
我的 cpp 文件中有以下结构:
struct EntityData
{
char globalId[512];
int mySpeed;
double x;
double y;
double z;
double h;
double p;
double r;
};
我有一个获取索引 # 和 returns 正确结构的方法:
extern "C" { __declspec(dllexport) getDataStruct(int index)
公开了此方法,因此我可以在我的 C# 应用程序中使用此方法,但我一直收到错误消息:
marshal directive exception.
我的 C# 代码:
[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;
}
我错过了什么?
从 msdn documentation page 它说:
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.
所以从你的结构来看
struct EntityData
{
char globalId[512];
// ...
}
您应该像这样定义您的 C# 结构:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct EntityDataRx
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 512)]
char[] globalId;
// ...
}
当你有 "a pointer to a null-terminated array of ANSI characters" 时使用 LPStr
但你拥有的是一个固定长度的数组。
终于解决了。
问题是从 cpp 结构我 return 指向结构的指针:
struct EntityData
{
char globalId[512];
int mySpeed;
double x;
double y;
double z;
double h;
double p;
double r;
};
在我的 C# 应用程序中:
[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));
我的 cpp 文件中有以下结构:
struct EntityData
{
char globalId[512];
int mySpeed;
double x;
double y;
double z;
double h;
double p;
double r;
};
我有一个获取索引 # 和 returns 正确结构的方法:
extern "C" { __declspec(dllexport) getDataStruct(int index)
公开了此方法,因此我可以在我的 C# 应用程序中使用此方法,但我一直收到错误消息:
marshal directive exception.
我的 C# 代码:
[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;
}
我错过了什么?
从 msdn documentation page 它说:
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.
所以从你的结构来看
struct EntityData
{
char globalId[512];
// ...
}
您应该像这样定义您的 C# 结构:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct EntityDataRx
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 512)]
char[] globalId;
// ...
}
当你有 "a pointer to a null-terminated array of ANSI characters" 时使用
LPStr
但你拥有的是一个固定长度的数组。
终于解决了。 问题是从 cpp 结构我 return 指向结构的指针:
struct EntityData
{
char globalId[512];
int mySpeed;
double x;
double y;
double z;
double h;
double p;
double r;
};
在我的 C# 应用程序中:
[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));