从c+编组结构数组+;在绞车中进行c# 我试图在Windows CE程序和紧凑框架2上从C++到C语言的结构。我在整理琴弦方面遇到了很多困难 我有这个C++代码: #define Console_Parameters_MAX 50 struct AllParameters { Parameter Parameters[Console_Parameters_MAX]; } ; struct Parameter { int Index; int Id; char Value[20]; }; extern "C" { BOOL GetAllConsoleParameters(AllParameters *pItem); } /* - not used #define Console_Parameters_MAX 50 struct AllParameters { Parameter Parameters[Console_Parameters_MAX]; } ; */ struct Parameter { int Index; int Id; char Value[20]; }; extern "C" { BOOL GetAllConsoleParameters(Parameter pItem[], int size); }

从c+编组结构数组+;在绞车中进行c# 我试图在Windows CE程序和紧凑框架2上从C++到C语言的结构。我在整理琴弦方面遇到了很多困难 我有这个C++代码: #define Console_Parameters_MAX 50 struct AllParameters { Parameter Parameters[Console_Parameters_MAX]; } ; struct Parameter { int Index; int Id; char Value[20]; }; extern "C" { BOOL GetAllConsoleParameters(AllParameters *pItem); } /* - not used #define Console_Parameters_MAX 50 struct AllParameters { Parameter Parameters[Console_Parameters_MAX]; } ; */ struct Parameter { int Index; int Id; char Value[20]; }; extern "C" { BOOL GetAllConsoleParameters(Parameter pItem[], int size); },c#,c++,arraylist,compact-framework,marshalling,C#,C++,Arraylist,Compact Framework,Marshalling,这是对应的c代码: 这就是我调用它的方式: AllParameters item = new AllParameters(); if (AppAPI.GetAllConsoleParameters(ref item)) { var array = item.Parameters; } 当我调用GetAllConsoleParameters时,会得到exception NotSupportedException。我尝试了许多配置,但都没有成功 有人能就如何实现这一目标提出建议吗 提前感谢这

这是对应的c代码:

这就是我调用它的方式:

AllParameters item = new AllParameters();
if (AppAPI.GetAllConsoleParameters(ref item)) {
   var array = item.Parameters;
}
当我调用GetAllConsoleParameters时,会得到exception NotSupportedException。我尝试了许多配置,但都没有成功

有人能就如何实现这一目标提出建议吗


提前感谢

这在Windows桌面上对我很有效。您可能必须在C DLL和C#DllImport属性中将调用约定更改为Cdecl,因为我在这里读到Cdecl是Windows CE上的标准:

C代码:

extern "C" {
  __declspec(dllexport) BOOL __stdcall GetAllConsoleParameters(AllParameters *pItem)
  {
    pItem->Parameters[0].Index = 0;
    pItem->Parameters[0].Id = 42;
    CopyMemory(&pItem->Parameters[0].Value[0], "Hello World", 12);
    pItem->Parameters[1].Index = 1;
    pItem->Parameters[1].Id = 43;
    CopyMemory(&pItem->Parameters[1].Value[0], "Hello World 43", 15);
    return TRUE;
  }
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
struct Parameter
{
    int Index;
    int Id;
    //char Value[20];
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
    string Value;
};

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
struct AllParameters
{
    //Parameter Parameters[Console_Parameters_MAX];
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
    Parameter[] Parameters;
};

class Program
{
    [DllImport("MarshalC.dll", CallingConvention = CallingConvention.StdCall)]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool GetAllConsoleParameters(ref AllParameters pItem);

    static void Main(string[] args)
    {
        var size = Marshal.SizeOf<AllParameters>();
        AllParameters all = new AllParameters();
        bool result = GetAllConsoleParameters(ref all);
    }
}
C#代码:

[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi)]
结构参数
{
整数指数;
int-Id;
//字符值[20];
[Marshallas(UnmanagedType.ByValTStr,SizeConst=20)]
字符串值;
};
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi)]
结构所有参数
{
//参数参数[控制台参数最大值];
[Marshallas(UnmanagedType.ByValArray,SizeConst=50)]
参数[]参数;
};
班级计划
{
[DllImport(“MarshalC.dll”,CallingConvention=CallingConvention.StdCall)]
[返回:Marshallas(UnmanagedType.Bool)]
静态外部布尔GetAllConsoleParameters(参考所有参数pItem);
静态void Main(字符串[]参数)
{
var size=Marshal.SizeOf();
AllParameters all=新的AllParameters();
bool结果=GetAllConsoleParameters(参考全部);
}
}

这在Windows桌面上对我很有效。您可能必须在C DLL和C#DllImport属性中将调用约定更改为Cdecl,因为我在这里读到Cdecl是Windows CE上的标准:

C代码:

extern "C" {
  __declspec(dllexport) BOOL __stdcall GetAllConsoleParameters(AllParameters *pItem)
  {
    pItem->Parameters[0].Index = 0;
    pItem->Parameters[0].Id = 42;
    CopyMemory(&pItem->Parameters[0].Value[0], "Hello World", 12);
    pItem->Parameters[1].Index = 1;
    pItem->Parameters[1].Id = 43;
    CopyMemory(&pItem->Parameters[1].Value[0], "Hello World 43", 15);
    return TRUE;
  }
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
struct Parameter
{
    int Index;
    int Id;
    //char Value[20];
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
    string Value;
};

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
struct AllParameters
{
    //Parameter Parameters[Console_Parameters_MAX];
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
    Parameter[] Parameters;
};

class Program
{
    [DllImport("MarshalC.dll", CallingConvention = CallingConvention.StdCall)]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool GetAllConsoleParameters(ref AllParameters pItem);

    static void Main(string[] args)
    {
        var size = Marshal.SizeOf<AllParameters>();
        AllParameters all = new AllParameters();
        bool result = GetAllConsoleParameters(ref all);
    }
}
C#代码:

[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi)]
结构参数
{
整数指数;
int-Id;
//字符值[20];
[Marshallas(UnmanagedType.ByValTStr,SizeConst=20)]
字符串值;
};
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi)]
结构所有参数
{
//参数参数[控制台参数最大值];
[Marshallas(UnmanagedType.ByValArray,SizeConst=50)]
参数[]参数;
};
班级计划
{
[DllImport(“MarshalC.dll”,CallingConvention=CallingConvention.StdCall)]
[返回:Marshallas(UnmanagedType.Bool)]
静态外部布尔GetAllConsoleParameters(参考所有参数pItem);
静态void Main(字符串[]参数)
{
var size=Marshal.SizeOf();
AllParameters all=新的AllParameters();
bool结果=GetAllConsoleParameters(参考全部);
}
}

我会这样做

        [StructLayout(LayoutKind.Sequential)]
        public struct AllParameters {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
            public Parameter[] Parameters;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct Parameter {
          public int Index;
          public int Id;
          [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
          public byte[] Value;
        }

        [DllImport("exemple.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
        public static extern bool GetAllConsoleParameters(ref IntPtr pItem);


        static void Main(string[] args)
        {
            AllParameters allParameters = new AllParameters();
            allParameters.Parameters = new Parameter[50];
            IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(allParameters));

            int z = Marshal.SizeOf(allParameters);

            if (GetAllConsoleParameters(ref ptr))
            {
                Marshal.PtrToStructure(ptr, allParameters);
                Parameter[] parameters = allParameters.Parameters;
            }

        }

我会这样做

        [StructLayout(LayoutKind.Sequential)]
        public struct AllParameters {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
            public Parameter[] Parameters;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct Parameter {
          public int Index;
          public int Id;
          [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
          public byte[] Value;
        }

        [DllImport("exemple.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
        public static extern bool GetAllConsoleParameters(ref IntPtr pItem);


        static void Main(string[] args)
        {
            AllParameters allParameters = new AllParameters();
            allParameters.Parameters = new Parameter[50];
            IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(allParameters));

            int z = Marshal.SizeOf(allParameters);

            if (GetAllConsoleParameters(ref ptr))
            {
                Marshal.PtrToStructure(ptr, allParameters);
                Parameter[] parameters = allParameters.Parameters;
            }

        }

我的解决方案,C++代码:

#define Console_Parameters_MAX 50

struct AllParameters {
  Parameter Parameters[Console_Parameters_MAX];
} ;

struct Parameter { 
  int Index;
  int Id; 
  char Value[20];
};

extern "C" {
   BOOL GetAllConsoleParameters(AllParameters *pItem);
}
/* - not used
#define Console_Parameters_MAX 50

struct AllParameters {
  Parameter Parameters[Console_Parameters_MAX];
} ;
*/

struct Parameter { 
  int Index;
  int Id; 
  char Value[20];
};

extern "C" {
   BOOL GetAllConsoleParameters(Parameter pItem[], int size);
}
以及相应的c#代码:

和代码调用:

ConsoleParameter[] item = new ConsoleParameter[50];
if (AppAPI.GetAllConsoleParameters(item, 50)) {
   var array = item;
}

谢谢帮助< /P> < P> >我的解决方案,C++代码:

#define Console_Parameters_MAX 50

struct AllParameters {
  Parameter Parameters[Console_Parameters_MAX];
} ;

struct Parameter { 
  int Index;
  int Id; 
  char Value[20];
};

extern "C" {
   BOOL GetAllConsoleParameters(AllParameters *pItem);
}
/* - not used
#define Console_Parameters_MAX 50

struct AllParameters {
  Parameter Parameters[Console_Parameters_MAX];
} ;
*/

struct Parameter { 
  int Index;
  int Id; 
  char Value[20];
};

extern "C" {
   BOOL GetAllConsoleParameters(Parameter pItem[], int size);
}
以及相应的c#代码:

和代码调用:

ConsoleParameter[] item = new ConsoleParameter[50];
if (AppAPI.GetAllConsoleParameters(item, 50)) {
   var array = item;
}


非常感谢您的帮助

异常的消息是什么?字符串是一个类,并不等同于char数组。在C++中,字符数组以“0”结尾。因此,在C语言中,使用字节[]代替字符数组。在相当长的一段时间里,我还没有使用C++,但我非常确信<代码> char []/COD>和 String []/Cord>不等价。我想您可能只需要在c#code中使用
字符串
。@jdweng字符串不会被封送,抱歉字节非字符串。。。复制错误…异常的消息是什么?字符串是一个类,不等同于char数组。在C++中,字符数组以“0”结尾。因此,在C语言中,使用字节[]代替字符数组。在相当长的一段时间里,我还没有使用C++,但我非常确信<代码> char []/COD>和 String []/Cord>不等价。我想您可能只需要在c#code中使用
字符串
。@jdweng字符串不会被封送,抱歉字节非字符串。。。复制错误…请使用compact framework 2.0。未实现Charset.Ansi我尝试使用“C:\Program Files(x86)\Microsoft.NET\SDK\CompactFramework\v2.0\WindowsCE\mscorlib.dll”并将其放入不包含Cdecl的库中。也许我的图书馆过时了?使用compact framework 2.0。未实现Charset.Ansi我尝试使用“C:\Program Files(x86)\Microsoft.NET\SDK\CompactFramework\v2.0\WindowsCE\mscorlib.dll”并将其放入不包含Cdecl的库中。也许我的库已经过时了?我尝试您的解决方案,但在Marshal.SizeOf(allParameters)中抛出异常,异常为:NotsupportedException。枚举调用约定仅包含一个元素WinApi。(我使用框架:CompactFramework2.0和VS2008)。不明白为什么…请确保使用最新的代码和结构。我在最初发布的代码中遇到了类似的错误,并进行了更改。发布的代码不再给出此错误。“z”的值为1400=50*28,这是正确的。因此,该代码将LPTR ptr传递给非托管内存空间中预先分配的1400字节内存块;看起来CE不支持Cdecl,所以消除了CallingConvention选项。我尝试了您的解决方案,但在Marshal.SizeOf(allParameters)中抛出异常,异常为:NotsupportedException。枚举调用约定仅包含一个元素WinApi。(我使用框架:CompactFramework2.0和VS2008)。不明白为什么…请确保使用最新的代码和结构。我在最初发布的代码中遇到了类似的错误,并进行了更改。发布的代码不再给出此错误。“z”的值为1400=50*28,这是正确的。因此,该代码将LPTR ptr传递给非托管内存空间中预先分配的1400字节内存块;看起来CE不支持Cdecl,所以取消了选项调用约定。