我有一个用非托管C++写的COM Dll,它暴露了一个com接口。 idl的简单示例如下所示:传递从托管c + +到COM接口指针的指针C#
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创建的Interop导入此COM对象,以便我可以使用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是通过导入 和导入这两个ComTestLib消费者为控制台应用程序项目添加引用。我的目标是获得ObjectToPass的实例,我的控制台应用程序中,并传递给消费者调用下面
#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;
}
公共方法PassObject作为表演这个代码将无法编译。编译器无法将参数1从'IObjectToPassPtr'转换为'Interop :: ComTest :: IObjectToPass ^'。我做了不同的尝试,但似乎IObjectToPass *不能被转换为'Interop :: ComTest :: IObjectToPass ^。有没有办法做到这一点?
blech!你究竟在做什么?不会直接C++/CLI(没有COM)更容易? –
看起来你可能想要[Marshal.GetUniqueObjectForIUnknown](https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.getuniqueobjectforiunknown(v = vs.110).aspx)?这将(出现)给你一个托管的'Object :: Consumer'实例用于你的非托管'obj'接口。 –
我模拟了我要移动的场景,太复杂了,不能在这里解释。我有第三方COM对象,它是从主应用程序传递给一个com unmanaged dll,我需要用一个.NET代替这个unmanged dll,所以我必须通过并使用第三方com对象。 –