C++ Builder6如何使用C#生成的COM lib(TLB)

sinat_18967637 2015-06-15 04:20:10
最近公司有个项目的合作机构,需要导入对方的私有格式数据再在我们的系统中作分析。对方使用C#2010生成的COM接口供我们调用,但是怎么搞都不能正常运行,求高手帮忙。
具体如下:
对方提供了一些dll及对应COM的.tlb文件,以regasm /codebase TestCommonData.dll /tlb:TestCommonData.tlb的方式注册了文件。之后导入C++Builder 6.0的时候为Project->Import Type Library,找到对应的Lib,Palette Page选择COM+,然后点击Create Unit,之后生成了TestCommonData_TLB.cpp/.h 文件。其中包含几个Interface:ITest,ITestData,ITestSet,ITestDescription,每个Interface包含几个Methods和几个属性。其中ITest是属于最外层的接口(大概这么叫吧),包含了两个方法:Retriever(wchar_t * fileName),Release();属性:Name(可以通过GetName()获得,C++builder中好像给成了get_Name()),然后还可以通过GetTestData(),GetTestSet(),GetDescription()方法获得相应的ITestData等类型的指针,然后再调用里面的方法啥的。现在问题因为以前没有接触过COM这些东西,对方提供的示例也是在VC++下的(但是目前由于其他限制我们只能应用在C++Builder中),在VC下可以成功,就是在C++Builder下初始化有问题。
对方提供示例:
Test *test_ptr;
::CoInitialize(NULL);
ITestPtr p(__uuidof(TestCommonData::Test));
test_ptr= p;
test_ptr->Retriever(L"E:\\Temp\\Test.test");
之后再使用GetName()之类的方法就行了。
C++Builder下我也想模仿对方的使用方式:
//Test *test_ptr;
//::CoInitialize(NULL);
//ITestPtr p(__uuidof(TestCommonData::Test)); //报错
//test_ptr= p;
//test_ptr->Retriever(L"E:\\Temp\\Test.test");
但是报错说第三行那里Improper use type ITestPtr,估计是C++Builder这边没有这种构造方式。之后Google了一下,使用CreateInstance方法:
HRESULT hr;
ITest* test_ptr= 0 ;
//std::cout<< "the pointer address is " << test_ptr<< std::endl;
::CoInitialize(NULL);
//std::cout<< "the pointer address is " << test_ptr<< std::endl;
hr = CoCreateInstance(CLSID_Test,0,CLSCTX_INPROC_SERVER,DIID_ITest,(void**)&pA);
//std::cout<< "the pointer address is " << test_ptr<< std::endl;
test_ptr->Retriever(L"E:\\Temp\\Test.test");
每次到左后一行都会跳到BCB的CPU窗口。一下方案也是:
ITestPtr pTestObj;
::CoInitialize(NULL);
pTestObj= CreateComObject(CLSID_Test);
pTestObj->Retrieve(L"E:\\Temp\\Test.test");
COM这块真是没什么概念,再加上时间不等人,也不能从头开始搞起,来求助让大家看看是不是哪里有问题,不胜感激 T_T
(邀请的几个大神是系统推荐的,无耻的伸手党第一次CSDN发帖,若扰见谅)
...全文
1207 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
我不懂电脑 2015-06-16
  • 打赏
  • 举报
回复
用import activex的功能导入组件
sinat_18967637 2015-06-16
  • 打赏
  • 举报
回复
谢妖哥这也是一种初始化方式。 问题发现鸟,不是初始化的问题。后来才发现是穿进去的参数问题,因为Retrieve()方法需要一个BSTR类型的参数,但是我直接传了一个wchar_t*类型的参数。将那个文件名用SysAllocString(wchar_t* name)方法转换成BSTR就能够读取了。(⊙﹏⊙)b,搞了好久是因为类型转换的问题。似乎VS里面有直接转换的方式啥的,在VS里面直接Retrieve(wchar_t * filename)就没问题,但是在BCB里面就得转换一下,不知道是不是姿势不对? 现在的问题是明明有个方法GetData(long Index)就是ITestSet中的方法,但是编译就是报错说GetData不是ITestSet的member,囧。。。继续研究吧 Anyway,十分感谢妖哥
ccrun.com 2015-06-16
  • 打赏
  • 举报
回复
这样试试吧
::CoInitialize(NULL);
Test *test_prt = CreateComObject(CLSID_Test);
if (test_prt)
    test_prt->Retrieve(L"E:\\Temp\\Test.test");
....
sinat_18967637 2015-06-16
  • 打赏
  • 举报
回复
妖哥方式有效。 唉,对各种字符串这边不是十分了解,基础不牢害死菜鸟啊。准备结帖。 PS:之前说的member问题是由于系统中两个版本的tlb引起的,非技术性问题。
ccrun.com 2015-06-16
  • 打赏
  • 举报
回复
引用 2 楼 sinat_18967637 的回复:
谢妖哥这也是一种初始化方式。 问题发现鸟,不是初始化的问题。后来才发现是穿进去的参数问题,因为Retrieve()方法需要一个BSTR类型的参数,但是我直接传了一个wchar_t*类型的参数。将那个文件名用SysAllocString(wchar_t* name)方法转换成BSTR就能够读取了。(⊙﹏⊙)b,搞了好久是因为类型转换的问题。似乎VS里面有直接转换的方式啥的,在VS里面直接Retrieve(wchar_t * filename)就没问题,但是在BCB里面就得转换一下,不知道是不是姿势不对? 现在的问题是明明有个方法GetData(long Index)就是ITestSet中的方法,但是编译就是报错说GetData不是ITestSet的member,囧。。。继续研究吧 Anyway,十分感谢妖哥
C++Builder里访问COM要代入字符串的话,可以用WideString类型,如:
test_prt->Retrieve(WideString(L"E:\\Temp\\Test.test"));

703

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder ActiveX/COM/DCOM
社区管理员
  • ActiveX/COM/DCOM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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