关于SDK接口中的指针问题
来源:互联网 发布:知豆汽车 编辑:程序博客网 时间:2024/05/24 07:34
关于SDK接口中的指针问题
黄延冬,2009.9.10
本文涉及到两个问题:
1. C#向C++写的SDK传入指针时,指针内外不一样造成了无法正确访问相关变量
2. C#定义带有数组的结构体的问题
-------------------------------------------------------------------------------------------------------------------
今天和同事调试SDK的对外支持时发现的一个问题,原因是SDK接口中用到了指针。
SDK的接口中使用指针本身没有问题,但在有些情况下却会出现奇怪的现象。
在SDK的接口中,用到了一个自定义结构的指针,在上层程序调用该接口时,把被初始化了的该结构指针传入SDK,在SDK中记录该指针。正常情况下,只要外部的该内存没有被破坏而且可访问,则SDK内部也可以正常使用该指针。这在C++调用此接口时没有发现问题,运行正常。但是今天和同事调试的时候,客户使用的是C#,在调用该接口时没有问题,但后续调用其它接口时,SDK内部使用到了该指针(之前记录在SDK中的),此时该指针已不能使用,其值已被改变,但在上层程序查看该内存,并没有发现什么不正常的情况。结果弄了半天,也没有弄明白,也不清楚原因。有望高手回复此贴。
在涉及到的结构中,定义了一个整型数据成员:int Value[16];
注:以下为C++中定义的数据结构
结构如下:
struct stu_test
{
long channel;
long index;
long datalength;
long reserved;
int value[16];
double dbset;
long lchang;
long lHeight;
};
SDK的接口定义如下:
void SetVSystemParam( unsigned long lHandle, stu_test *pStuTest );
void StartPlay( unsigned long lHandle );
下面只讨论C#调用时发生的情况,因为其它的大部分都用的是C++,它没有问题。
在调用SetVSystemParam()后,SDK的该接口实现函数中打印stu_test的值没有问题,都是对的,在SDK内部,会有一个变量stu_test *m_pStuTest;记录传入的pStuTest的指针,在StartPlay()接口中会用到m_pStuTest;,但在这个接口中发现此指针的值已经不对,完全变样了,但是这个指针是没有变化的(已经排除了这种低级错误),即指向的确是同一块内存,但是其值不一样,在调用StartPlay()接口时,上层保存该结构的变量依然有效,而且其值也没有任何改变。这就奇怪了。
后来又发现一个问题,在上层中,使用VC的内存查看,发现上层保存的变量地址(记为MA)和SDK中记录的该指针(记为MS)是不一样的!
而且对于C#中结构的定义,和C++中也不大相同,特别是对于涉及到的数组int value[16];的定义更是完全不一样。开始的时候,上层定义为:
int[] value;
结果在sizeof()打印结构的大小时,显示是不正确的,该成员是被当成一个指针,只占用了4个字节,后来改成在它的前面增加占用了16个int的空间([MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
),后面再定义int[] value;,最后的结构大致如下:
public struct stu_test
{
int channel;
int index;
int datalength;
int reserved;
MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)
int[] value;
double dbset;
int lchang;
int lHeight;
};
虽然使用sizeof()查看其占用的内存大小没错,但是其内容还是不正确的,通过内存查看,发现结构和内存根本对不上。在内存中,前面的4个字节应该是channel占用的,但实际上,整个数据是从开始内存的位置向后偏移大概是12个字节的位置开始的,而且在value的内存位置,根本不是value的值,反倒其后面的成员dbset等等的值跑到了value的前面!在初始化结构时,对value是进行了new操作,即分配了内存。在查看value的内存时,它的位置显然不在stu_test结构体所占用的内存范围内!所以这样定义还是不对,即使是结构体的内存大小没错!
后来实在没办法,就把int value[16];拆开成16个成员变量进行了定义,这次再查看内存没有错了,都对得上了。注意:这只是内存对得上,该问题和前面调用SDK时SDK内部的内存值不对没有关系。
问题1的解决方法是修改SDK。在SDK内部自己分配内存,然后在SetVSystemParam()中把外部传入的内存值拷贝到SDK自己的内存地址中。这样,外面再调用StartPlay()时就没有问题了。但这只是其中的一个解决方法,而且可能不能适用于所有的情况。
请各位发表高见,我只熟悉C++,不熟悉C#,没有用过。
- 关于SDK接口中的指针问题
- C中的关于指针的优先问题
- C++中的关于指针的问题
- 关于c++类中的指针成员问题
- 关于C++中的接口的问题
- 关于meego-sdk-0524安装中的几点问题。
- 关于DirectX高级动画书中的SDK升级问题
- 关于百度地图SDK在" SDKInitializer.initialize(this);"初始化报空指针的问题
- 关于butterknife在Eclipse中的空指针的问题
- 关于微信 调用js-sdk接口报错的问题
- 指针在接口中的用法
- 关于C++中的指针
- 关于实现Serialable接口的类中的serialVersionUID问题
- 关于 Java 中的接口
- 关于接口中的方法
- 关于JAVA中的接口!
- 关于C#中的接口
- 关于Android sdk隐藏接口的使用
- 从运行环境来看云计算的特征
- 图形快速记忆数据库并发容易引起的问题
- 12个Flex常用功能代码
- 如何配置 SQL Server 2005 以允许远程连接
- java mail send
- 关于SDK接口中的指针问题
- 开启关闭Linux防火墙
- servlet中处理用户非法登录页面
- 侦探式的DBA-解决数据库死锁和阻塞问题
- curl_setopt里面的参数意义
- svn其他操作
- 搞笑但很现实
- 计划任务定时执行
- javascript弹出窗口问题总结