从C#调用C DLL函数 - 参数struct太大或太复杂而无法编组

时间:2015-06-23 12:06:23

标签: c# c struct marshalling dllimport

我在使用C#从C DLL调用函数时遇到问题。我试图编组结构,但一个例外告诉我,我的结构太大或太复杂而无法编组......我已经为完整大小计算了15256个字节。

原始C函数如下所示:

int32_t CN_API SetConfig(int32_t handle, int32_t bId, ModeEnum Mode, ParamStruct params);

我在C#中定义的结构如下所示:

struct ParamStruct
{
    int param1;
    ...
    //Here are some primitve arrays and variables...
    ...
    structArray1[16]
    //    |__...some integers
    //    |__structA
    //            |__...some variables

    int param8

    structB
    //    |__...some integer arrays and a float array
    //    |__structArray2[16]
    //            |__...some variables

    enum param9
    ...
    //here are some more structs and struct arrays
    ...
}

我知道“语法”不正确。只是你知道我的意思;)。

现在我想调用此函数并将ParamStruct传递给它。

我的问题是,我该怎么做?你们中有谁有解决问题的好主意吗? 使用IntPtr可行吗? 或者是在C#中重写我的结构的最好方法,那么它是不是很复杂?

如果您需要更详细的信息,请告诉我。

1 个答案:

答案 0 :(得分:-1)

我通过重新定义本机方法以获取字节*参数&来解决了类似的问题。手动将结构复制到字节数组。

public override void ToByteArray(out byte[] bEeprom)
{
  int arrOffs, arrOffs1, arrOffs2;
  int length = Size();
  int ptrOffset = 0;
  byte[] convString;
  int maxLen;

  IntPtr ptr = Marshal.AllocHGlobal(length);

  Marshal.WriteByte(ptr, ptrOffset, renumerationMode);
  ptrOffset += sizeof(byte);
  Marshal.WriteInt16(ptr, ptrOffset, (short)vendorID);
  ptrOffset += sizeof(short);
  Marshal.WriteInt16(ptr, ptrOffset, (short)productID);
  ptrOffset += sizeof(short);
  Marshal.WriteInt16(ptr, ptrOffset, (short)deviceID);
  ptrOffset += sizeof(short);
  Marshal.WriteByte(ptr, ptrOffset, config);
  ptrOffset += sizeof(byte);
  Marshal.WriteByte(ptr, ptrOffset, eepromVersion);
  ptrOffset += sizeof(byte);
  Marshal.WriteInt16(ptr, ptrOffset, hwVersion);
  ptrOffset += sizeof(short);
  for (arrOffs = 0; arrOffs < configFlags.Length; arrOffs++)
  {
    Marshal.WriteByte(ptr, ptrOffset, configFlags[arrOffs]);
    ptrOffset += sizeof(byte);
  }
......
  Debug.Assert(ptrOffset == length);

  bEeprom = new byte[length];
  Marshal.Copy(ptr, bEeprom, 0, length);
  Marshal.FreeHGlobal(ptr);
}