【问题标题】:How to convert the returned interface variable by a method to object?如何将方法返回的接口变量转换为对象?
【发布时间】:2013-05-08 05:08:26
【问题描述】:

我正在使用 c# 包装器,在 c++ 库中,被调用的函数返回一个指向类对象的指针。 在 c# 包装器中,如果我调用该方法,它会返回一个接口变量。 该接口变量为空,因此我无法获取值。 我应该如何处理该接口变量以获取值。 请任何人帮助我。

在下面的代码中我们有 ROOTNET.Interface.NTH1F 它是一个接口,其中 ROOTNET.NTH1F 是一个类

using ROOTNET.Utility;
using ROOTNET.Interface;

NTH1F g = new ROOTNET.NTH1F("g", "background removal", doubleArrayX.Length - 1,    
    doubleArrayX);

g.SetContent(doubleArrayY);
g.GetXaxis().SetRange(xmin, xmax);

ROOTNET.NTH1F bkg = new ROOTNET.NTH1F(g);
bkg.Reset();

bkg.Add(g.ShowBackground(80, ""));

在上面我希望将背景删除的值保存在 bkg 中,但 bkg 包含全零,请您帮我将 g 的背景删除值保存到 bkg 中。

ShowBackground(int niter, string option) 方法的代码在哪里

public unsafe virtual NTH1 ShowBackground (int niter, string option)
{
    NetStringToConstCPP netStringToConstCPP = null;
    NetStringToConstCPP netStringToConstCPP2 = new NetStringToConstCPP (option);
    NTH1 bestObject;
    try
    {
        netStringToConstCPP = netStringToConstCPP2;
        int num = *(int*)this._instance + 912;
        bestObject = ROOTObjectServices.GetBestObject<NTH1> (calli ((), this._instance, niter, netStringToConstCPP.op_Implicit (), *num));
    }
    catch
    {
        ((IDisposable)netStringToConstCPP).Dispose ();
        throw;
    }
    ((IDisposable)netStringToConstCPP).Dispose ();
    return bestObject;
}

【问题讨论】:

  • 我不同意最后的投票。这是特定的,但不是本地的。我可以看到未来的访客再次提出这个问题,即使不太可能。请提供一个投票理由,以便在未来结束问题。
  • 任何人请帮助我,对不起,如果我没有正确地提出问题,我是一个学习者。
  • 请提供一些您尝试过的示例。代码,也就是。
  • 问题问得不好的问题不是,我们很讨厌地不会回答,而是我们不会理解,你在问什么,在什么情况下。您应该花更多时间提出问题,以确保每个人都能正确理解问题所在。
  • 没关系,我的直截了当的问题是,有一个 c++ dll,它有一个函数,其返回类型是指向类对象的指针,现在我正在使用 .net 包装器到该 c++ dll,在这个包装器中,该方法的副本返回一个接口变量,所以每当我调用该方法时,我手中都会有一个空值,这是我的问题兄弟

标签: c# c++ interface dllimport


【解决方案1】:

您不能将 C++ 返回的指针值视为接口(我猜除非它是 COM 接口)。 C++ 和 C# 类和接口可能(并且很可能确实)具有不同的低级结构,因此您不能简单地将一个转换为另一个。

唯一的方法是围绕库返回的 C++ 类编写另一个包装器。它应该看起来不那么像:

C++/DLL:

__declspec(dllexport) void * ReturnInstance()
{
    return new MyClass();
}

__declspec(dllexport) void MyClass_CallMethod(MyClass * instance)
{
    instance->Method();
}

C#:

[DllImport("MyDll.dll")]
private static extern IntPtr ReturnInstance();

class MyClassWrapper
{
     private IntPtr instance;

     [DllImport("MyDll.dll")]
     private static extern void MyClass_CallMethod(IntPtr instance);

     public MyClassWrapper(IntPtr newInstance)
     {
         instance = newInstance;
     }

     public void Method()
     {
         MyClass_CallMethod(instance);
     }
}

// (...)

IntPtr myClassInstance = ReturnInstance();
MyClassWrapper wrapper = new MyClassWrapper(myClassInstance);
wrapper.Method();

希望这会有所帮助。

【讨论】:

  • 但是我这里既没有 c++ dll 的源代码也没有 c# wrapper dll
  • 如果 C++ 返回一个类或接口,那么您肯定至少应该有头文件。如果是这样,您可以将该 DLL 包装在您自己的 DLL 中,为您的 C++ 包装器编写一个 C# 包装器,这应该可以工作。但是,在完成这个项目之前,请确保您对 DLL 和 P/Invoke 机制有足够的了解,因为从我读到的内容来看,它似乎让您有点不知所措。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多