[C#] C#调用C语言编写的DLL时遇到的结构体问题

nimafeigou 2010-05-08 01:56:44
C语言结构体:

typedef struct stateStruct {
uschar sim_start; // starting & ending flags
uschar sim_end;
PGPS_t PGPS; //这些都是结构体内嵌套的结构体,可以忽略,不是问题所在
PSPW_t PSPW;
PWPR_t PWPR;
PRDP_t PRDP;
DPDC_t DPDC;
DCE1_t DCE1;
E1E2_t E1E2;
E2E3_t E2E3;
E3E4_t E3E4;
E4E5_t E4E5;
E5PG_t E5PG;
data_t rf[2][16]; // 问题所在的数组
data_t rf_dirty[2][16]; // 问题所在的数组
data_t crf[21]; // 问题所在的数组
} state_t;


C语言返回给C#的函数:
state_t get_state()
{
return state;
}


C#中的结构体:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct stateStruct
{
public byte sim_start; // starting & ending flags
public byte sim_end;
public PGPSStruct PGPS;
public PSPWStruct PSPW;
public PWPRStruct PWPR;
public PRDPStruct PRDP;
public DPDCStruct DPDC;
public DCE1Struct DCE1;
public E1E2Struct E1E2;
public E2E3Struct E2E3;
public E3E4Struct E3E4;
public E4E5Struct E4E5;
public E5PGStruct E5PG;
public uint[,] rf; //问题所在数组
public uint[,] rf_dirty; //问题所在数组
public uint[] crf; //问题所在数组
}

C#接收C语言结构体的语句:
stateStruct state = new stateStruct();

state.rf = new uint[2, 16];
state.rf_dirty = new uint[2, 16];
state.crf = new uint[21];

state = get_state();

我在使用一个C语言编写的DLL时发生的问题,我需要在C#中获得C语言程序state_t结构体中的数据,我用的方法比较笨,就是在C#程序中创造一个完全一摸一样的结构体去接收返回的结构体,我的问题在于执行 state = get_state(); 时会报错。

错误信息为:
其他信息: 方法的类型签名与 PInvoke 不兼容。


请大神帮忙看下应该怎么做才能让我取得这些数据?

新手上路,请多指教
...全文
404 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
xingyuebuyu 2010-05-09
  • 打赏
  • 举报
回复
如果可以在DLL进行如下修改
void get_state(state_t *st)
{

}

一般来说结构体都是通过ref的方式去调用,将结果通过参数返回
nimafeigou 2010-05-08
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 jiangsheng 的回复:]
默认的列集处理不支持嵌套结构。保险的方法是用XML或者C++/CLI做中转,如果你对互操作比较熟的话也可以自己写一个列集器,参考http://msdn.microsoft.com/en-us/magazine/cc164123.aspx和http://msdn.microsoft.com/en-us/magazine/cc164193.aspx
[/Quote]

看了一下感觉挺复杂了,因为比较急,我就没有看下去了,不过还是谢谢

实在做不到我只能用最笨的方法,多写一些返回函数,一个一个数据去取了
nimafeigou 2010-05-08
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 mjp1234airen4385 的回复:]
7楼的也许可以。
或者可以试试:
public IntPtr rf; //问题所在数组
public IntPtr rf_dirty; //问题所在数组
public IntPtr crf; //问题

最后在做数据转换
[/Quote]

我尝试做过一个测试,就是在C语言中写了一个简单的结构体,里面只有一个一维数组,同样在C#代码中也是这样的一个简单结构体,可是返回结构体时同样是这个错误,所以我认为应该是数组这方面用的方法不对?

指针的话我本身就学的不好,不太会用,如果按照您说的这样改了C#的话,我C的结构体内的类型要怎么改呢?
蒋晟 2010-05-08
  • 打赏
  • 举报
回复
默认的列集处理不支持嵌套结构。保险的方法是用XML或者C++/CLI做中转,如果你对互操作比较熟的话也可以自己写一个列集器,参考http://msdn.microsoft.com/en-us/magazine/cc164123.aspx和http://msdn.microsoft.com/en-us/magazine/cc164193.aspx
mjp1234airen4385 2010-05-08
  • 打赏
  • 举报
回复
7楼的也许可以。
或者可以试试:
public IntPtr rf; //问题所在数组
public IntPtr rf_dirty; //问题所在数组
public IntPtr crf; //问题

最后在做数据转换
nimafeigou 2010-05-08
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 ckl881003 的回复:]
unsigned short int 是 16
C#里对应的是uint16
[/Quote]

谢谢,可是我还是觉得是数组方面的问题,我觉得类型的转换应该没有问题
ckl881003 2010-05-08
  • 打赏
  • 举报
回复
Win32 Types CLR Type
char, INT8, SBYTE, CHAR System.SByte
short, short int, INT16, SHORT System.Int16
int, long, long int, INT32, LONG32, BOOL , INT System.Int32
__int64, INT64, LONGLONG System.Int64
unsigned char, UINT8, UCHAR , BYTE System.Byte
unsigned short, UINT16, USHORT, WORD, ATOM, WCHAR , __wchar_t System.UInt16
unsigned, unsigned int, UINT32, ULONG32, DWORD32, ULONG, DWORD, UINT System.UInt32
unsigned __int64, UINT64, DWORDLONG, ULONGLONG System.UInt64
float, FLOAT System.Single
double, long double, DOUBLE System.Double


附送C#调用DLL的数据类型映射表一张
ckl881003 2010-05-08
  • 打赏
  • 举报
回复
unsigned short int 是 16
C#里对应的是uint16
nimafeigou 2010-05-08
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 ckl881003 的回复:]
data_t 是什么东西?结构体?如果是结构体那么C#里也要用data_t
[/Quote]

不是结构体,只是 uint

补上C语言中的宏定义

typedef unsigned long long uslong; // unsigned 64 bit <= target dependent
typedef unsigned int usint; // unsigned 32 bit
typedef signed long long slong; // signed 64 bit <= target dependent
typedef signed int sint; // signed 32 bit
typedef unsigned char uschar;

typedef usint inst_t;
typedef usint address_t;
typedef usint data_t;
xingyuebuyu 2010-05-08
  • 打赏
  • 举报
回复
  [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct stateStruct
{
public byte sim_start; // starting & ending flags
public byte sim_end;
public PGPSStruct PGPS;
public PSPWStruct PSPW;
public PWPRStruct PWPR;
public PRDPStruct PRDP;
public DPDCStruct DPDC;
public DCE1Struct DCE1;
public E1E2Struct E1E2;
public E2E3Struct E2E3;
public E3E4Struct E3E4;
public E4E5Struct E4E5;
public E5PGStruct E5PG;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=32)]
public uint[] rf; //问题所在数组
[MarshalAs(UnmanagedType.ByValArray, SizeConst=32)]
public uint[] rf_dirty; //问题所在数组
[MarshalAs(UnmanagedType.ByValArray, SizeConst=21)]
public uint[] crf; //问题所在数组
}


先用一维数组来代替二维数组,然后数组都要指定长度
ckl881003 2010-05-08
  • 打赏
  • 举报
回复
data_t 是什么东西?结构体?如果是结构体那么C#里也要用data_t

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧