c#调用c,c++ dll 嵌套结构体转换

ztcztf 2014-11-13 09:14:28
现在用C#调用不知道是C还是C++写的DLL库,涉及到结构体嵌套时参数传递的问题,在网上找了各种方法都跟我这个不太一样,也试了各种方法都过不去,求助。
c++结构体如下,DLL无法改写。


//被嵌套结构体
typedef struct {
CHAR a[ 19 ];
CHAR b;
WORD c;
} OBE, *LPOBE;

//外层结构体
typedef struct {
DWORD d;
OBE ObeInfo;
} CARD, *LPCARDT;


尝试了C#的结构体定义如下:

//被嵌套结构体
[StructLayout(LayoutKind.Sequential)]
public struct OBE{
[MarshalAs(UnmanagedType.ByValArray,SizeConst=19)]
public char[] a;
public char b;
public uint16 c;


//外层结构体
[StructLayout(LayoutKind.Sequential)]
public struct CARD{
public uint d;
//这个地方不知道怎么写了!!!
[MarshalAs(UnmanagedType.Struct)]
public OBE ObeInfo;
}


报AccessViolationException异常,提示我正在访问不可读写的内存。

以上。
...全文
451 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
ztcztf 2014-11-14
  • 打赏
  • 举报
回复
现已明确知道是内层结构体不正确,把内层结构体注掉后对方返回参数错误的errorCode,不报异常。
Saleayas 2014-11-14
  • 打赏
  • 举报
回复
[StructLayout(LayoutKind.Sequential, CharSet= CharSet.Ansi)]
public struct OBE{
[MarshalAs(UnmanagedType.ByValTStr,SizeConst=19)]
public string a;
public sbyte b;
public UInt16 c;
}
  
//外层结构体
[StructLayout(LayoutKind.Sequential)]
public struct CARD{
public UInt32 d;
public OBE ObeInfo;
}
ztcztf 2014-11-14
  • 打赏
  • 举报
回复
函数调用时实例化外层结构体CARD时需要先实例化内层结构体OBE么? CARD Card = new CARD; Card.d = 123; OBE Obe = new OBE(); Obe.a = "aaa"; Obe.b = 123; Obe.c = 456; 函数调用: FunctionA(ref Card); 这样写是否有问题?
ztcztf 2014-11-14
  • 打赏
  • 举报
回复
以上几种方法挨个都试过了,仍然报AccessViolationException异常。 继续求答案。
hwangt0 2014-11-14
  • 打赏
  • 举报
回复
[StructLayout(LayoutKind.Sequential)]
public struct OBE{
[MarshalAs(UnmanagedType.ByValTStr,SizeConst=19)]
public string a;
public byte b;
public UInt16 c;
}
 
//外层结构体
[StructLayout(LayoutKind.Sequential)]
public struct CARD{
public UInt32 d;
public OBE ObeInfo;
}
WM_JAWIN 2014-11-14
  • 打赏
  • 举报
回复
把char改为byte就对了。其它的看似正常
xian_wwq 2014-11-14
  • 打赏
  • 举报
回复
引用 楼主 ztfljy 的回复:
现在用C#调用不知道是C还是C++写的DLL库,涉及到结构体嵌套时参数传递的问题,在网上找了各种方法都跟我这个不太一样,也试了各种方法都过不去,求助。 c++结构体如下,DLL无法改写。

//被嵌套结构体
typedef struct {
CHAR   a[ 19 ];
CHAR   b;
WORD  c;
} OBE, *LPOBE;

//外层结构体
typedef struct {
DWORD   d;
OBE ObeInfo;
} CARD, *LPCARDT;
尝试了C#的结构体定义如下:

//被嵌套结构体
[StructLayout(LayoutKind.Sequential)]
public struct OBE{
[MarshalAs(UnmanagedType.ByValArray,SizeConst=19)]
public char[] a;
public char b;
public uint16 c;
}

//外层结构体
[StructLayout(LayoutKind.Sequential)]
public struct CARD{
public uint d;
//这个地方不知道怎么写了!!!
[MarshalAs(UnmanagedType.Struct)]
public OBE ObeInfo;
}
报AccessViolationException异常,提示我正在访问不可读写的内存。 以上。
StructLayout的约定最好声明完整 例如

 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
在结构体中嵌套结构体,没有特殊的写法 直接写就可以

   public struct SServer
    {
       public SAdvance m_advanceCfg;
    }
char[] 也可以用string来对应

         [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 19)]
        public string mStrTemp;
ztcztf 2014-11-14
  • 打赏
  • 举报
回复
引用 11 楼 xian_wwq 的回复:
肯定要实例化, 否则返回的数据写的非法地址去了 代码似乎少了一句 Card.ObeInfo = new OBE();
谢谢提醒,是我写错了。但是问题不在这。 找于问题的根源了,DLL接口的其它参数传的有问题,非结构体的问题, 谢谢各位的热心,一百分平均分给回答的各位。
xian_wwq 2014-11-14
  • 打赏
  • 举报
回复
引用 6 楼 ztfljy 的回复:
函数调用时实例化外层结构体CARD时需要先实例化内层结构体OBE么? CARD Card = new CARD; Card.d = 123; OBE Obe = new OBE(); Obe.a = "aaa"; Obe.b = 123; Obe.c = 456; 函数调用: FunctionA(ref Card); 这样写是否有问题?
肯定要实例化, 否则返回的数据写的非法地址去了 代码似乎少了一句 Card.ObeInfo = new OBE();
ztcztf 2014-11-14
  • 打赏
  • 举报
回复
引用 9 楼 save4me 的回复:
你调用的时候有给结构体分配内存吗,Marshal.AllocHGlobal?如果你内存都没分配就访问,会抛出异常。
我参考你给的第二条链接里面第一句话是
引用
This article talks about marshaling structures using PInvoke which has a pointer to an array of another structure as a member.
我理解是内层结构体的指针在外层结构体里面,而不是结构体本身。 我这个DLL定义里被嵌套的结构体用的不是指针吧?所以我不确定应不应该使用你提供的四个方法。
save4me 2014-11-14
  • 打赏
  • 举报
回复
你调用的时候有给结构体分配内存吗,Marshal.AllocHGlobal?如果你内存都没分配就访问,会抛出异常。 下面的几个函数你可能需要: Marshal.AllocHGlobal Marshal.PtrToStructure Marshal.StructureToPtr Marshal.FreeHGlobal 参考: C#调用C++的DLL 所有数据类型转换方式 Marshalling Complicated Structures using PInvoke
引用 8 楼 ztfljy 的回复:
现已明确知道是内层结构体不正确,把内层结构体注掉后对方返回参数错误的errorCode,不报异常。
iyomumx 2014-11-13
  • 打赏
  • 举报
回复
CHAR -> byte

111,098

社区成员

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

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

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