2011-08-15 75 views
0

.NETに変換できない大きなレガシーC++ 6.0コードベースで作業しています。私がしようとしているのは、C#の新しい機能をすべてCOMラッパーでラップし、C++から呼び出すことです。私は、C#から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; 
} 

// 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 
}; 

答えて

0

タイプライブラリをインポートすることによって、C++で生成されたヘッダあなたはIDispatchインターフェースを介して使用されるライブラリをインポートします。これにより、プリミティブ(int、string、fload、配列など)と他のオブジェクト(IDispatchも実装する必要があります)のみを公開することができます。

したがって、(IEquationCOM/Equationを公開するのと同じように)新しいIDispatchインターフェイス+実装の定義でStruct(struct IVariableCOM)を置き換える必要があります。

低レベルの解決策(COMルール:メモリ管理など): C++からのCOMオブジェクトのみを使用している場合は、idlファイルを抽出してC++プロジェクトでコンパイルできますIVariableCOM定義にアクセスできます。

関連する問題