COM组件如何避免结构体重复定义

兔子先生-zhang 2012-03-30 10:37:19
是这样的:
假如我写了两个组件:组件A和组件B,都包含了一个自定义的结构体类型,如:
typedef struct POINT{
int x;
int y;
}POINT;

然后我利用import在客户端调用这两个组件的时候就会提示POINT重复定义。

我的组件是按照网上找的这个方法写的:
1) 从IUnknown继承的自定义接口
把数据结构直接传送给基于VTable接口的方法,只适用于由MIDL编译生成的proxy/
stub DLL调度的接口,不能用于Invoke();(参UserDefinedDataType(1))
a.在一个新的.h文件中定义自定义数据结构.
b.在.idl文件最前面加入这个.h文件,比如:
#include "MyStruct.h"
c.给从IUnknown派生的接口加入使用了自定义数据结构的方法。
d.在客户程序的stadafx.h最下面加入#import指令,如:
#import "..\test3.tlb" no_namespace
在生成的.tlh文件中,会自动包含了用户自定义数据结构的定义。


然后生成的两个.tlh文件中都有POINT的定义,就出现了重复定义的问题,我试过用条件编译的方法修改.tlh文件,但是当VC6.0再次加载.tlh文件的时候,会自动把我的条件编译语句去掉,所以条件编译的方法是行不通的。

请问,各位com高手,有什么好的办法可以避免重复定义。
...全文
408 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
兔子先生-zhang 2012-04-19
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 的回复:]
在IDL中出现两次重复的结构体定义本身就是不好的方法,只需要在一个IDL中定义就行了,在另一个IDL中可以包含这个IDL,作用跟#include相同
[/Quote]

谢谢你的回答,我初学com,只会简单的用法,还请多指教。

嗯,你的方法很不错,我试试!
redui 2012-04-19
  • 打赏
  • 举报
回复
再跟你解释详细一点吧,在 a.idl 中(odl文件也可以)定义结构体,在 b.idl 中增加语句 import "a.idl"。
在你的程序中只需要#import "b.tbl"即可,编译器帮你生成两个头文件,一个是 a.h,包含结构体定义,另一个是 b.h,它里面自动增加了 #include "a.h" 语句。是不是跟你的CPP/H结构类似?不用再担心结构体重复的问题了吧?
redui 2012-04-19
  • 打赏
  • 举报
回复
在IDL中出现两次重复的结构体定义本身就是不好的方法,只需要在一个IDL中定义就行了,在另一个IDL中可以包含这个IDL,作用跟#include相同
向立天 2012-04-19
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 的回复:]
引用 1 楼 的回复:
用 rename。
比如 #import "..\test3.tlb" rename("POINT","POINT_A")


你好,谢谢你的回答。

rename的作用是将POINT重命名成POINT_A了吗?

我用了命名空间的方法,避免了重复定义的问题,但是现在的另一个问题是:
我从其中的一个组件中得到一个点数据,比如说PointA,PointA的……
[/Quote]
名字空间就是最好的方法
关于数据结构
强制类型转换不可以么
WaistCoat05 2012-04-19
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 jawyzh 的回复:]

引用 9 楼 的回复:
使用命名空间是比较好的解决方法


但说实话,在每个自定义结构体前都需要加命名空间名,很麻烦,我仍然在寻找更好的方法。。。如果有的话。
[/Quote]

没有其他更好的方法,命名空间就是解决这个问题。就像C++里的命名空间一样。
兔子先生-zhang 2012-04-18
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 的回复:]
使用命名空间是比较好的解决方法
[/Quote]

但说实话,在每个自定义结构体前都需要加命名空间名,很麻烦,我仍然在寻找更好的方法。。。如果有的话。
joyancy21 2012-04-18
  • 打赏
  • 举报
回复
使用命名空间是比较好的解决方法
Tinary3v0 2012-03-31
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 fishjam 的回复:]

用 rename。
比如 #import "..\test3.tlb" rename("POINT","POINT_A")
[/Quote]
我见的多数都是采用这种方式,例如EOF怕与别的类冲突就定义为XEOF或者MYEOF等
兔子先生-zhang 2012-03-31
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]
类型名称不要取得太简单,不然重名是肯定的
[/Quote]

谢谢你的回答。

这个重名是我有意的,我想在两个组件之间利用这个结构体传递数据。
兔子先生-zhang 2012-03-31
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]
组件不能改的话就用1#的方法,不过话说组件是你自己做的,名字加个前缀也长不了多少。。。
[/Quote]

你好,谢谢你的回答。

组件是自己写的,也可以改,但是我想在组件之间利用这个POINT结构体传递点数据,如果改了的话就没有办法传递数据了。

有什么办法可以解决不同命名空间中相同结构体之间的数据传递问题?
兔子先生-zhang 2012-03-31
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]
用 rename。
比如 #import "..\test3.tlb" rename("POINT","POINT_A")
[/Quote]

你好,谢谢你的回答。

rename的作用是将POINT重命名成POINT_A了吗?

我用了命名空间的方法,避免了重复定义的问题,但是现在的另一个问题是:
我从其中的一个组件中得到一个点数据,比如说PointA,PointA的定义是COREADDATALib::POINT,其中COREADDATALib是类库名,也就是默认的命名空间名,然后我想传递给另一组件的变量PointB,PointB属于NORMLib命名空间,我的运行的时候编译器提示:cannot convert from 'struct COREADDATALib::POINT' to 'struct NORMLib::POINT'。

如何解决不同命名空间中相同结构体之间的数据传递问题?
kyotrue 2012-03-31
  • 打赏
  • 举报
回复
组件不能改的话就用1#的方法,不过话说组件是你自己做的,名字加个前缀也长不了多少。。。
三条猫 2012-03-31
  • 打赏
  • 举报
回复
类型名称不要取得太简单,不然重名是肯定的
hztj2005 2012-03-30
  • 打赏
  • 举报
回复
不清楚com.
但条件编译指令应该在这个文件
a.在一个新的.h文件中定义自定义数据结构.
fishjam 2012-03-30
  • 打赏
  • 举报
回复
用 rename。
比如 #import "..\test3.tlb" rename("POINT","POINT_A")

3,245

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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