【发布时间】:2017-06-21 02:17:06
【问题描述】:
我有一个用非托管 C++ 编写的 COM Dll,它公开了一个 com 接口。 idl的简单示例如下所示:
import "oaidl.idl";
import "ocidl.idl";
[
object,
uuid(A806FAED-FCE2-4F1B-AE67-4B36D398508E),
dual,
nonextensible,
pointer_default(unique)
]
interface IObjectToPass : IDispatch{
[propget, id(1)] HRESULT Name([out, retval] BSTR* pVal);
[propput, id(1)] HRESULT Name([in] BSTR newVal);
};
[
uuid(B99537C0-BEBC-4670-A77E-06AB5350DC23),
version(1.0),
]
library {
importlib("stdole2.tlb");
[
uuid(FB7C7D08-0E38-40D2-A160-0FC8AE76C3CF)
]
coclass ObjectToPass
{
[default] interface IObjectToPass;
};
};
所以 IObjectToPass 接口是暴露的接口。 现在我已经在 C# 中实现了一个 .NET 库 (ObjectConsumer),它通过 tlbimp 这个 COM 对象创建的 Interop 导入,因此我可以使用 IObjectToPass 接口。下面是这个库的示例代码:
using Interop.ComTest;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;ComTestLib
using System.Threading.Tasks;
namespace ObjectConsumer
{
public class Consumer
{
public void PassObject(IObjectToPass passobj)
{
string str = passobj.Name;
}
}
}
c++ 和 c# 模块编译都没有问题
现在我在 C++ 中创建了一个简单的控制台应用程序,它支持 CLR,通过 import 导入 ComTestLib 和消费者添加对控制台应用程序项目的引用。我的目标是在我的控制台应用程序中获取 ObjectToPass 的实例,并传递给调用公共方法 PassObject 的消费者,如下所示
#include "stdafx.h"
#import "..\Debug\ComTest.tlb" no_namespace, raw_interfaces_only
int main()
{
CoInitialize(NULL);
IObjectToPassPtr obj;
HRESULT hr = obj.CreateInstance(__uuidof(IObjectToPass) );
ObjectConsumer::Consumer^ consumer = gcnew ObjectConsumer::Consumer();
obj->put_Name(_T("MyName"));
consumer->PassObject(obj);
CoUninitialize();
return 0;
}
此代码无法编译。编译器无法将参数 1 从“IObjectToPassPtr”转换为“Interop::ComTest::IObjectToPass ^”。我做了不同的尝试,但似乎 IObjectToPass* 无法转换为 'Interop::ComTest::IObjectToPass^。有办法吗?
【问题讨论】:
-
我已经模拟了里面我要搬家的场景,太复杂了,这里就不解释了。我有一个第三方 com 对象,它从主应用程序传递到一个 com 非托管 dll 我需要用一个 .NET 替换这个非托管 dll,所以我必须传递并使用第三方 com 对象。
标签: c# c++ .net com language-interoperability