从托管c+;向COM接口指针传递指针+;到.NETC# 我有一个COM DLL写在非托管C++中,它公开了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对象,这样我就可以使用IObjectToPass接口了。下面是此库的示例代码:从托管c+;向COM接口指针传递指针+;到.NETC# 我有一个COM DLL写在非托管C++中,它公开了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; }; };,c#,c++,.net,com,language-interoperability,C#,C++,.net,Com,Language Interoperability,所以IObjectToPass接口就是公开的接口。 现在我已经在C#中实现了一个.NET库(ObjectConsumer),它通过tlbimp创建的互操作导入这个COM对象,这样我就可以使用IObjectToPass接口了。下面是此库的示例代码: using Interop.ComTest; using System; using System.Collections.Generic; using System.Linq; using System.Text;ComTestLib using
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模块均编译无问题< /P> 现在我在C++中支持了一个简单的控制台应用程序,它通过导入导入了CuestLIB 消费者添加对控制台应用程序项目的引用。我的目标是在控制台应用程序中获取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^”。是否有办法做到这一点?< P>跳过COM接口,只在C++中导出工厂函数。< /P>
#define MY_API __declspec(dllexport)
#ifdef __cplusplus
# define EXTERNC extern "C"
#else
# define EXTERNC
#endif
EXTERNC MY_API IObjectToPass* APIENTRY MyFactory(void);
EXTERNC MY_API void APIENTRY SomeFunction(IObjectToPass* handle);
// Implementation:
MY_API IObjectToPass* APIENTRY MyFactory(void)
{
return new ObjectToPass();
}
MY_API void APIENTRY SomeFunction(IObjectToPass* handle)
{
handle->DoFunction();
}
// And then export any needed functions too.
现在在C#中:
考虑至少去掉C的三种形式中的一种,以简化设计,否则我建议的方法就行了,我以前也用过 我已经模拟了我必须搬家的场景,太复杂了,无法在这里解释。我有一个第三部分com对象,它从主应用程序传递到一个com非托管dll。我需要用一个.NET dll替换这个非托管dll,所以我必须传递并使用第三部分com对象。
public class MyWrapper{
IntPtr myReference;
public ObjectWrapper()
{
try
{
this.myReference = MyFactory();
if (myReference == IntPtr.Zero)
{
throw "Error or something";
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
throw e;
}
}
//Path to dll
[DllImport(lib_path)]
private static extern IntPtr MyFactory();
[DllImport(lib_path)]
private static extern void SomeFunction(IntPtr toTrigger);
}