一个关于在IDL文件中union结构体的问题,真是搞不懂,为什么微软可以我不可以!

Snow_1980 2008-05-11 12:43:07
在微软的DIRECTX的SDK文档中可以查看到三维矩阵结构体D3DMMATRIX,定义如下:
typedef struct _D3DMMATRIX {
union {
struct {
D3DMVALUE _11, _12, _13, _14;
D3DMVALUE _21, _22, _23, _24;
D3DMVALUE _31, _32, _33, _34;
D3DMVALUE _41, _42, _43, _44;
};
D3DMVALUE m[4][4];
};
} D3DMMATRIX;
DIRECTX很多借口都用到了这个结构体做参数

我建立了一个ATL工程,在IDL文件中加入了D3DMMATRIX的定义,并在接口中使用D3DMMATRIX结构体作为参数传递,结构编译出错:
.\adsf.idl(35) : error MIDL2143 : parameter must not derive from a non-rpcable union : [( Parameter 'pVal' ) ]
.\adsf.idl(35) : error MIDL2161 : union has at least one arm without a case label : [ Field ( Parameter 'pVal' ) ]
.\adsf.idl(35) : error MIDL2161 : union has at least one arm without a case label : [ Field 'm' ( Parameter 'pVal' ) ]
.\adsf.idl(36) : error MIDL2143 : parameter must not derive from a non-rpcable union : [( Parameter 'newVal' ) ]
.\adsf.idl(36) : error MIDL2161 : union has at least one arm without a case label : [ Field ( Parameter 'newVal' ) ]
.\adsf.idl(36) : error MIDL2161 : union has at least one arm without a case label : [ Field 'm' ( Parameter 'newVal' ) ]

报错的意思就是因为在结构体中使用了union,好像是要求我对D3DMMATRIX添加swith_is或swith_type属性,那样的话又必须在D3DMMATRIX中再添加一个新的参数,就改变了D3DMMATRIX的定义!

所以真是很搞不懂,不知道微软的DIRECTX是如何解决这个问题的,不知那位高手知道如何解决,请指点我一下,不胜感激!!百分相赠!
...全文
279 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
healer_kx 2008-05-11
  • 打赏
  • 举报
回复
高深,看不懂。
Kudeet 2008-05-11
  • 打赏
  • 举报
回复

typedef [public] struct _D3DMMATRIX {
union {
struct {
D3DMVALUE _11, _12, _13, _14;
D3DMVALUE _21, _22, _23, _24;
D3DMVALUE _31, _32, _33, _34;
D3DMVALUE _41, _42, _43, _44;
};
D3DMVALUE m[4][4];
};
} D3DMMATRIX;
Snow_1980 2008-05-11
  • 打赏
  • 举报
回复
谢谢各位的解答,不过好像还是没有解决这个问题……

首先加public属性的意思是即使接口没用用到IDL中定义的结构,也将其导出至tlb中(我是这样理解的,不知对不对)

现在编译的错误好像就是无法识别其中的union,按照4楼的意思就是要加一个标志符对union进行标志,但是DIRECTX中很多接口就是传递的D3DMMATRIX指针对性,其中并无标志参数,例如下面这个接口就无

HRESULT SetTransform(
D3DMTRANSFORMSTATETYPE State,
CONST D3DMMATRIX* pMatrix,
D3DMFORMAT Format
);

搞不懂,明天看看DIRECTX的SDK中有没有定义的IDL文件可以参考一下
yueyeli 2008-05-11
  • 打赏
  • 举报
回复
不会,帮忙顶起来
jameshooo 2008-05-11
  • 打赏
  • 举报
回复 1
idl中导出结构体的语法跟头文件是不一样的,首先要按照1楼说的添加public属性。

按照你提供的编译错误提示,应该是结构中使用了NON-RPCABLE的成员变量,意思是这个变量类型无法被远程过程调用正确列集结构体,因为无法识别出union中的具体类型,按照下面的例子来定义:

typedef [public, switch_type(short)] union _WILLIE_UNION_TYPE // switch_type(short)表示用于这个联合的指示符的类型是short类型
{
[case(24)] float fMays; // 当联合指示符的值是24时,用fMays成员
[case(25)] double dMcCovey; // 当联合指示符的值是25时,用dMcCovey成员
[default] ; // 其它值是错误的,不对应任何成员
} WILLIE_UNION_TYPE;

typedef [public] struct _WINNER_TYPE
{
[switch_is(sUniformNumber)] WILLIE_UNION_TYPE w; // 这个w就是一个union,当要使用w的值时,以sUniformNumber成员的值来确定使用联合中的哪个成员
short sUniformNumber; // 这个就是联合指示符,它的值可以是24或者25
} WINNER_TYPE;

事实上,switch_type和switch_is属性仅仅用于数据的列集和散列,对于C/C++语言调用者来说是没有任何意义的

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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