使用C ++包装器的托管代码中的本机c ++实例

时间:2010-11-24 18:39:49

标签: c# c++-cli native

我们正面临互操作问题,我们在C#中编写客户端exe,我们有一些用COM dll编写的遗留代码和一个本机C ++静态库。 我们需要使用它们来完成C#client中的功能。我们已经使用interop向COM dll添加了referance并且能够 在C#Code中创建COM类的实例。现在这个COM类方法接受的参数是nactive C ++的对象,COM中的一些方法 class需要参数,这些参数是在c ++静态库中声明的类的对象。因为我们无法在中创建C ++本机类的实例 C#,我们决定在本机类上编写C ++ / CLI包装器,并在C#代码中创建warpper实例,并通过本地类访问实例 warpper并将其传递给在C#client中创建的COM类。问题是当我们将本机对象指针(作为IntPtr)传递给COM类时,我们不会将本机对象初始化为其值。可能是什么问题呢?我们如何通过托管c ++包装器将本机对象传递回C#代码?

 //Natvie C++ class
 class __declspec(dllexport) CConfiguration
 {

    public :
         CConfiguration(void);
         virtual ~CConfiguration(void);
         void SetIPAddress(const char *IPAddress);
         void SetPort(const char*Port);
         void GetIPAddress(char *IPAddress);
         void GetPort(char *Port);
    Private:
         std::string IPAddress;
         std::string Port;

 }


//Managed C++ Class  
public ref class ManagedConfigruation
{
         public :
        ManagedConfigruation(){}
        ~ManagedConfigruation(){}
         CConfiguration  *myConfiguration;          
              IntPtr  GetObjectOfConfigurationPtr();     
}

IntPtr ManagedConfigruation::GetObjectOfConfigurationPtr()
{
     myConfiguration = new CConfiguration();
     myConfiguration.SetIPAddress("127.0.0.1");
     myConfiguration.SetPort("6200");
     //Convert native object to IntPtr and return to C# class
     return System::IntPtr(myConfiguration);
};

 //C# class on client exe
 public class CSharpClass
{

    //Wrapper of Managed C++ class
    ManagedConfiguration objManagedConfiguration = new ManagedConfiguration();
    IntPtr objPtr = objManagedConfiguration.GetObjectOfConfigurationPtr();

    //Belwoo COMObject needs object of type CConfiguration native C++ class    
    COMObject.Initialize(objPtr);  //Here is the problem object does not contain anything


}

3 个答案:

答案 0 :(得分:1)

采用类似原始指针的COM方法不兼容自动化。这很不寻常,COM方法在这种情况下采用COM接口指针。您最好使用对象浏览器检查转换类型库后的样子。当参数类型为 object 时,您遇到了问题。

最好还是在C ++ / CLI中保留COM接口代码。

答案 1 :(得分:0)

我从未使用过COMObject.Initialize(x),不确定它是做什么的。

但是,如果你想从你的IntPtr中获取IUnknown,你可以这样做:

object pUnk = Marshal.GetObjectForIUnknown(objPtr);

另见:http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.getobjectforiunknown.aspx

答案 2 :(得分:0)

Initialize不是COM方法,它是我们自己的方法,它将IntPtr作为参数,实际上是一个本机C ++对象。