C#调用C封装dll结构体指针

MrSoda 2014-07-11 11:59:02
原来一直用MFC做,最近项目要用C#学了学基本的东西还是有差距啊,调用底层函数的时候卡主了,求路过大神帮忙
先是C++的定义:
typedef struct TagData_struct{
double value; //返回点的数值
long time; //返回点的时间,秒
int status; //返回点的状态
}TagData;

初始化:
char *tagNames[MEM_PAGE_ITEMS];
for ( int i=0; i<MEM_PAGE_ITEMS; i++ )
{
tagNames[i]=(char*)malloc( TAGNAME_LENGTH*sizeof(char) );
memset(tagNames[i],0,TAGNAME_LENGTH);
strcpy( tagNames[i], PtName[i].GetBuffer());
PtName[i].ReleaseBuffer();
}

TagData *g_pTagData;
g_pTagData =(TagData *)malloc( MEM_PAGE_ITEMS*sizeof(TagData) );
memset( g_pTagData, 0, MEM_PAGE_ITEMS*sizeof(TagData) );
调用:
iRet =RTDBDao.GetRTDataByBatch( tagNames , g_pTagData, g_iPtCount );
函数原型:
int GetRTDataByBatch( char* tagNames[],TagData * pTagData,long nCount )

下面是我写的C#的:
[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct TagData
{
public double value; //返回点的数值
public long time; //返回点的时间,秒
public int status; //返回点的状态
};

class LibWrapper
{
[DllImport("DataInterface.dll", CharSet = CharSet.Ansi, EntryPoint = "GetRTDataByBatch", CallingConvention = CallingConvention.Cdecl)]
public extern static int GetRTDataByBatch([In] string[] tagName, IntPtr tgs, long nCount);
}

main函数中:

string[] tagNames = new string[2];
tagNames[0] = "Dev_Test00";
tagNames[1] = "Dev_Test01";

IntPtr[] ptArray = new IntPtr[1];
ptArray[0] = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(TagData)) * 10);
IntPtr pt = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)) * 1);
Marshal.Copy(ptArray, 0, pt, 1);

iRet = LibWrapper.GetRTDataByBatch(tagNames, pt, 2);

for (int i = 0; i < 2; i++)
{
TagData tagInfo = (TagData)Marshal.PtrToStructure((IntPtr)((UInt32)ptArray[0] + i * Marshal.SizeOf(typeof(TagData))), typeof(TagData));
double val = tagInfo.value;
long tm = tagInfo.time;
int state = tagInfo.status;
}

Marshal.FreeHGlobal(ptArray[0]);
Marshal.FreeHGlobal(pt);

取不到数据为什么呢? 哪里写错了?
...全文
372 11 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
相思梦 2014-07-17
  • 打赏
  • 举报
回复
引用 10 楼 zhenghaolan 的回复:
[quote=引用 9 楼 Windowsvipcuvs 的回复:] 返回结构滴头指针就可以 如果你觉得不爽那就不再 接收程序内定义结构体 玩指针一样很爽
能给段代码吗,还在入门。。[/quote] RtlMoveMemory 会用吗
MrSoda 2014-07-14
  • 打赏
  • 举报
回复
引用 9 楼 Windowsvipcuvs 的回复:
返回结构滴头指针就可以 如果你觉得不爽那就不再 接收程序内定义结构体 玩指针一样很爽
能给段代码吗,还在入门。。
allen0118 2014-07-12
  • 打赏
  • 举报
回复
恭喜楼主,这个问题留着,有用!
相思梦 2014-07-12
  • 打赏
  • 举报
回复
返回结构滴头指针就可以 如果你觉得不爽那就不再 接收程序内定义结构体 玩指针一样很爽
风吹腚腚凉 2014-07-11
  • 打赏
  • 举报
回复
typedef struct TagData_struct{ double value; //返回点的数值 long time; //返回点的时间,秒 int status; //返回点的状态 数据类型没对应吧,C#里面是int C++里面是long的话
MrSoda 2014-07-11
  • 打赏
  • 举报
回复
谢谢楼上各位,不是对齐的问题 查了大半天MSDN 参考这里 http://msdn.microsoft.com/zh-cn/library/hk9wyw21.aspx [DllImport("DataInterface.dll", CharSet = CharSet.Ansi, EntryPoint = "GetRTDataByBatch", CallingConvention = CallingConvention.Cdecl)] public extern static int GetRTDataByBatch([In] string[] tagName, [In,Out] TagData[] tgs, long nCount); 注意第二个参数的[In,Out]属性,单独的in或者out都不行 调用时初始化结构体数组 TagData[] tags = new TagData[2]; for (int i = 0; i < tags.Length; i++) { tags[i] = new TagData(); } iRet = LibWrapper.GetRTDataByBatch(tagNames, tags, 2); 这样就可以了
bigbaldy 2014-07-11
  • 打赏
  • 举报
回复
引用 5 楼 zhenghaolan 的回复:
[quote=引用 3 楼 bigbaldy 的回复:] C#里面的long是C++中的LONGLONG,所以C#结构体中time应该是int型的
这样啊,谢谢你和1L可是改完了我得到的数据还是不对的 如果把函数声明成 public extern static int GetRTDataByBatch([In] string[] tagName, ref TagData[] tgs, long nCount); 后面用结构体数组直接传参可以得到第一个值是正确的,可是后面又不对了[/quote] C++的TagData_struct声明要加#pragma pack(1)
MrSoda 2014-07-11
  • 打赏
  • 举报
回复
引用 3 楼 bigbaldy 的回复:
C#里面的long是C++中的LONGLONG,所以C#结构体中time应该是int型的
这样啊,谢谢你和1L可是改完了我得到的数据还是不对的 如果把函数声明成 public extern static int GetRTDataByBatch([In] string[] tagName, ref TagData[] tgs, long nCount); 后面用结构体数组直接传参可以得到第一个值是正确的,可是后面又不对了
风吹腚腚凉 2014-07-11
  • 打赏
  • 举报
回复
引用 2 楼 zhenghaolan 的回复:
[quote=引用 1 楼 wjfwd2010 的回复:] typedef struct TagData_struct{ double value; //返回点的数值 long time; //返回点的时间,秒 int status; //返回点的状态 数据类型没对应吧,C#里面是int C++里面是long的话
并没有吧,int、long都是4个byte啊[/quote] 好像不是吧?
bigbaldy 2014-07-11
  • 打赏
  • 举报
回复
C#里面的long是C++中的LONGLONG,所以C#结构体中time应该是int型的
MrSoda 2014-07-11
  • 打赏
  • 举报
回复
引用 1 楼 wjfwd2010 的回复:
typedef struct TagData_struct{ double value; //返回点的数值 long time; //返回点的时间,秒 int status; //返回点的状态 数据类型没对应吧,C#里面是int C++里面是long的话
并没有吧,int、long都是4个byte啊

111,092

社区成员

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

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

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