0

我有一个调用本机 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;

实例化 Phenomenom 对象的 C# 程序对 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++ 函数后打印出结构的值时,该结构尚未更新(即与调用 C++ 函数之前相同)。似乎 C++ 程序能够看到这些值并更新它们,但是在返回时,C# 永远不会看到对结构中值的更新。认为这是一个值与引用的问题,我什至尝试用 C# 程序中的一个类而不是结构来做到这一点。仍然没有运气。

问题:我需要什么样的封送处理才能让被调用的 C++ 函数能够更新传递给它的实际结构?

谢谢你。-Greg Edwards 完全沉浸式软件

4

3 回答 3

2

如果不查看 C# 函数的定义,就很难理解为什么这不起作用。我猜它看起来像这样

[DllImport("somedll.dll")]
public static extern Int16 rsttwi_temp(Phenomenon[] array);

我没有太多使用固定大小的本机数组的经验。但是您可以做的是更改 C++ 签名以采用指针而不是固定大小的数组,并将托管代码切换为通过引用传递。例如

[DllImport("somedll.dll")]
public static extern Int16 rsttwi_temp(ref Phenomenon value);

__declspec(dllexport) short int rsttwi_temp (phenomenon* phen)
于 2009-08-06T22:39:43.177 回答
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);
于 2010-12-24T20:18:47.533 回答
-2

C# 字符!= C++ 字符。

C# char == C++ wchar_t

C++ 字符 == C# 字节

于 2010-03-05T05:37:42.893 回答