我有一个调用本机C ++ DLL的C#程序。
C#有以下结构:
[StructLayout(LayoutKind.Sequential)]
public struct Phenomenon
{
[MarshalAs(UnmanagedType.U1)] public char Type;
[MarshalAs(UnmanagedType.R8)] public double Jd;
[MarshalAs(UnmanagedType.R8)] public double Loc_jd;
[MarshalAs(UnmanagedType.R8)] public double Angle;
[MarshalAs(UnmanagedType.U1)] public char Tran_dir;
[MarshalAs(UnmanagedType.I2)] public Int16 Warning;
}
C ++程序具有以下结构定义:
typedef struct
{
char type;
double jd;
double loc_jd;
double angle;
char tran_dir;
short int warning;
} phenomenon;
C#程序实例化Phenomenom对象具有以下对C ++方法的调用:
Phenomenon[] phenomena = new Phenomenon[6];
short status = rsttwi_temp(phenomena);
C ++只是更新结构并返回。这是C ++函数:
__declspec(dllexport) short int rsttwi_temp (phenomenon phen[1])
{
phen[0].type = 'Z';
phen[0].jd = 1.1;
phen[0].loc_jd = 2.2;
phen[0].angle = 3.3;
phen[0].tran_dir = 4.4;
phen[0].warning = '0';
return 0;
}
在C#程序中,当我在调用C ++函数后打印出struct的值时,struct还没有更新(即它与调用C ++函数之前的相同)。似乎C ++程序能够查看值并更新它们,但是在返回时,C#永远不会看到结构中值的更新。认为这是一个价值与参考问题,我甚至尝试用C#程序中的类来代替结构。仍然没有运气。
问题: 我需要编组什么才能让被调用的C ++函数能够更新传递给它的实际结构?
谢谢。 -Greg Edwards 完全浸入式软件
答案 0 :(得分:2)
如果不了解C#函数的定义,为什么这不起作用并不容易理解。我猜它看起来像这样但是
[DllImport("somedll.dll")]
public static extern Int16 rsttwi_temp(Phenomenon[] array);
我没有太多使用pinvoking固定大小的原生数组的经验。但是你可以做的是更改C ++签名以获取指针而不是固定大小的数组,并切换托管代码以通过引用传递。例如
[DllImport("somedll.dll")]
public static extern Int16 rsttwi_temp(ref Phenomenon value);
__declspec(dllexport) short int rsttwi_temp (phenomenon* phen)
答案 1 :(得分:1)
以这种方式使用:
C ++
__declspec(dllexport) short int rsttwi_temp (phenomenon* phen)
{
phen->jd = 1.1;
phen->loc_jd = 2.2;
phen->angle = 3.3;
phen->warning = 0;
return 0;
}
typedef struct
{
double jd;
double loc_jd;
double angle;
short int warning;
} phenomenon;
C#
[DllImport("somedll.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern Int16 rsttwi_temp(ref Phenomenon value);
[StructLayout(LayoutKind.Sequential)]
public struct Phenomenon
{
[MarshalAs(UnmanagedType.R8)]
public double Jd;
[MarshalAs(UnmanagedType.R8)]
public double Loc_jd;
[MarshalAs(UnmanagedType.R8)]
public double Angle;
[MarshalAs(UnmanagedType.I2)]
public Int16 Warning;
}
C#致电
Phenomenon phenomena = new Phenomenon();
short status = rsttwi_temp(ref phenomena);
答案 2 :(得分:-1)
C#char!= C ++ char。
C#char == C ++ wchar_t
C ++ char == C#byte