将struct数组从C ++传递给C#

时间:2011-08-15 13:25:33

标签: c# c++ com-interop

我正在使用无法转换为.NET的大型遗留C ++ 6.0代码库。我要做的是在C#中使用COM包装器编写所有新功能,并从C ++中调用它。我遇到过大量从C#调用C ++的文章,但反过来却很少。 对于简单类型,C#和C ++之间的交互对我来说很好,但是我遇到了一个问题,我需要将一个类型为Variable(用户定义)的数组从C ++传递给C#,当我导入类型库时,我得到以下内容我在c#

中声明数组的任何方法的行 由于无效的返回类型或参数类型

方法'ParseEquation'未发出

任何人都可以告诉我如何将用户定义的类的数组从C ++传递给C#代码这里是代码。

c#代码

//  Equation Parser


//Events Interface
[ComVisible(true), Guid("47C976E0-C208-4740-AC42-41212D3C34F0"), InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IEquation_EventsCOM
{
}

//COM Interface
[ComVisible(true), Guid("3F2DE348-0BDA-4051-92B5-9B7A59FD525D")]
public interface IEquationCOM
{
    [DispId(0)]
    string GetParserInfo();

    [DispId(1)]
    float ParseEquation(IVariableCOM[] varList, string expression);
}

[ComVisible(true), Guid("9E5E5FB2-219D-4ee7-AB27-E4DBED8E123E"), ClassInterface(ClassInterfaceType.None), ComSourceInterfaces(typeof(IEquation_EventsCOM))]
public class Equation : IEquationCOM
{
    public Equation()
    {
    }

    [ComVisible(true)]
    public string GetParserInfo()//List<Variable> varList, string expression)
    {
        Version version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
        string name = System.Reflection.Assembly.GetExecutingAssembly().GetName().FullName;
        return "Assemby Name: " + name + "   Version: " + version.ToString();
    }

    [ComVisible(true)]
    public float ParseEquation(IVariableCOM[] varList, string expression)
    {
        //test return value
        return 12.0000f;
    }
}


//  Equation Parser Helper Classes

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct IVariableCOM
{
    public string Name;
    public string Type;
    public float Value;
}

通过导入类型库

在C ++中生成的标头
// Machine generated IDispatch wrapper class(es) created with ClassWizard
/////////////////////////////////////////////////////////////////////////////
// IEquation_EventsCOM wrapper class

class IEquation_EventsCOM : public COleDispatchDriver
{
public:
    IEquation_EventsCOM() {}        // Calls COleDispatchDriver default     constructor
    IEquation_EventsCOM(LPDISPATCH pDispatch) : COleDispatchDriver(pDispatch) {}
    IEquation_EventsCOM(const IEquation_EventsCOM& dispatchSrc) :     COleDispatchDriver(dispatchSrc) {}

// Attributes
public:

// Operations
public:
};
/////////////////////////////////////////////////////////////////////////////
// IEquationCOM wrapper class

class IEquationCOM : public COleDispatchDriver
{
public:
    IEquationCOM() {}       // Calls COleDispatchDriver default constructor
    IEquationCOM(LPDISPATCH pDispatch) : COleDispatchDriver(pDispatch) {}
    IEquationCOM(const IEquationCOM& dispatchSrc) : COleDispatchDriver(dispatchSrc) {}

// Attributes
public:

// Operations
public:
    CString GetGetParserInfo();
    // method 'ParseEquation' not emitted because of invalid return type or parameter     type
};

1 个答案:

答案 0 :(得分:0)

您可以通过IDispatch界面导入要使用的库。这允许您只公开原始(int,string,fload,数组等)和其他对象(也必须实现IDispatch)。

所以你应该用一个新的IDispatch接口+实现定义替换Struct(struct IVariableCOM)(类似于你公开IEquationCOM / Equation)。

低级解决方案(您应该知道COM规则:内存管理等): 如果仅使用c ++中的COM对象,则可以提取idl文件,并在可以访问IVariableCOM定义的c ++项目中进行编译。