0

C# コードで 2 つの構造を作成しました。

[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 
        public class RollInformationCSharp 
        { 
            [MarshalAs(UnmanagedType.R8)] 
            public double rollDiameter; 

            [MarshalAs(UnmanagedType.R8)] 
            public double initialRoughness; 

            [MarshalAs(UnmanagedType.R8)] 
            public double finalRoughness; 

            [MarshalAs(UnmanagedType.R8)] 
            public double accumulateCombination; 

            [MarshalAs(UnmanagedType.R8)] 
            public double critialRollLength; 

            [MarshalAs(UnmanagedType.R8)] 
            public double rolledLength; 

            [MarshalAs(UnmanagedType.R8)] 
            public double percentageLifeRoll; 

            [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 256)] 
            public string rollName; 
         }; 

と :

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 
        public class MultiRollCSharp 
        { 
            [MarshalAs(UnmanagedType.I4)] 
            public int nbRoll; 

            public RollInformationCSharp[] tabRoll; 
        } 

C# コードでは、C++ dll の関数を呼び出します。

[DllImport("DLL_RaFTmodel.dll", CharSet = CharSet.Ansi)] 
        public static extern IntPtr DLL_FlesCalculation(MultiRollCSharp multiRollInfo, 
                                              CoilInformationCSharp coilInfo, 
                                              RollInformationCSharp rollInfo, 
                                              LimitsTypeCSharp LimitsSteel, 
                                              LimitsTypeCSharp LimitsRegulation, 
                                              LimitsTypeCSharp LimitsMachine, 
                                              FTInputsCsharp forceTensionInfo, 
                                              RaConstantsCSharp RaModelIn, 
                                              FTWeightCsharp FTmodelIn, 
                                              [In, MarshalAs(UnmanagedType.I4)] int strategy, 
                                              [In, MarshalAs(UnmanagedType.I4)] int rollLifeMaximization, 
                                              RaInputsCsharp RaDataIn, 
                                              char Version, 
                                              [In, MarshalAs(UnmanagedType.R4)] float errMax, 
                                              [Out, MarshalAs(UnmanagedType.I4)] out int error); 

C++ には、2 つの構造体もあります。

struct RollInformation 
{ 
    double rollDiameter; 
    double initialRoughnessRoll; 
    double finalRoughnessRoll; 
    double accumulateCombination; 
    double percentageLifeRoll; 
    double criticalRollLength; 
    double rolledLength; 
    char rollName[256]; 
}; 

struct MultiRollInformation 
{ 
    int nbRoll; 
    RollInformation* tabRoll; 
}; 

関数は次のようにも宣言されています。

extern EXPORTTOTEM_API  
MULTICURVETYPE* DLL_FlesCalculation( struct MultiRollInformation *multiRollInfo,                                     struct CoilInformation *coilInfo,  
             struct RollInformation *rollInfo, 
             struct LimitsType *LimitsSteel, 
             struct LimitsType *LimitsRegulation, 
             struct LimitsType *LimitsMachine, 
             struct FTInputs *forceTensionInfo, 
             struct RaConstants *constRaIn, 
             struct FTWeight *modelFTIn, 
             int strategy, 
             int rollLifeMaximization, 
             struct RaInputs *dataRaIn, 
                         char Version, 
             float errMax, 
             int &error);    

C# で構造体を埋める例:

MultiRollCSharp multiRollInfo = new MultiRollCSharp(); 
            for(int i = 0; i < 5; i++) 
            { 
                RollInformationCSharp rollInfo1 = GetRollInformation(); 
                int taille = 0; 
                if (multiRollInfo.tabRoll != null) 
                    taille = multiRollInfo.tabRoll.Length; 

                RollInformationCSharp[] tab = new RollInformationCSharp[taille +1]; 
                if (taille > 0) 
                { 
                    multiRollInfo.tabRoll.CopyTo(tab, 0); 
                } 
                tab[tab.Length-1] = rollInfo1; 
                multiRollInfo.tabRoll = tab; 

                multiRollInfo.nbRoll += 1; 
            } 

デバッグ モードでは、DLL への呼び出しの直前に、C# の両方の構造が正しい (multiRollInfo と rollInfo) です。C++ では、rollInfo が適切です。しかし、マルチロール情報には 5 つの要素がありますが、値が間違っています。

なにが問題ですか?どうすればこれを修正できますか?

ご助力ありがとうございます

4

3 に答える 3

3

実装では、次の C++ 構造体が宣言されたように扱います (余分な * に注意してください)。そのままでは、C# コードの要素は参照型 ( class) であり、ネイティブ表現がポインターであることを意味します。

struct MultiRollInformation 
{ 
    int nbRoll; 
    RollInformation** tabRoll; 
};

これを解決するには、RollInformationCSharpクラスをstruct. 同時に、パラメーターのマネージド シグネチャの 3 番目のパラメーターを作成する必要がDLL_FlesCalculationありrefます。

于 2009-07-17T06:50:11.773 に答える
0

MultiRollCSharp.tabRollはメモリ内の配列への参照(ポインタ)であるため、技術的には元の質問からの宣言は正しいです。ところで、あなたはRollInformationCSharpとMultiRollCSharpをクラスとして宣言しました、間違いですか?または入力エラー?

しかし、マーシャラーはそのような複雑な状況を処理することはできません。したがって、2つの方法があります。最初に、配列を構造自体に埋め込みます。

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct MultiRollCSharp
{
    [MarshalAs(UnmanagedType.I4)]
    public int nbRoll;
    [MarshalAs(UnmanagedType.ByValArray)]
    public RollInformationCSharp[] tabRoll;
}

struct MultiRollInformation 
{ 
    int nbRoll; 
    RollInformation tabRoll[];
};

これは、C#からC ++(配列の長さがわかっている)にマーシャリングする場合は正しく機能する必要がありますが、逆方向にマーシャリングしようとすると失敗します。この場合、マーシャラーのtabRoll配列の長さが不明であるためです。

2番目のオプションは、C#のtabRollを実際のポインター(IntPtr)に置き換え、それに応じて動作することです(Marshal.AllocHGlobalなどを使用してメモリを割り当てます)。この場合、c++構造は変更されません。これはより複雑なアプローチですが、より柔軟です。一般に、IntPtrsを使用してすべてを実行できます。

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct MultiRollCSharp
{
    [MarshalAs(UnmanagedType.I4)]
    public int nbRoll;
    IntPtr tabRoll;
}
于 2009-07-17T14:07:40.197 に答える
0

私が理解している場合:C ++では、1つの変更のみ:

struct MultiRollInformation
{
    int nbRoll;
    RollInformation** tabRoll;
};

C#で:

    public struct RollInformationCSharp
    {
        [MarshalAs(UnmanagedType.R8)]
        public double rollDiameter;
        public double initialRoughness;
        public double finalRoughness;
        public double accumulateCombination;
        public double critialRollLength;
        public double rolledLength;
        public double percentageLifeRoll;

        [MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = 256)]
        public string rollName;
    };
   [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public class MultiRollCSharp
    {
        [MarshalAs(UnmanagedType.I4)]
        public int nbRoll;

        public RollInformationCSharp[] tabRoll;
    }

呼び出すDLLからの関数:

  [DllImport("DLL_RaFTmodel.dll", CharSet = CharSet.Ansi)]
    public static extern IntPtr DLL_FlesCalculation(MultiRollCSharp multiRollInfo,
                     CoilInformationCSharp coilInfo,
                     ref RollInformationCSharp rollInfo,
                     LimitsTypeCSharp LimitsSteel,
                     LimitsTypeCSharp LimitsRegulation,
                     LimitsTypeCSharp LimitsMachine,
                     FTInputsCsharp forceTensionInfo,
                     RaConstantsCSharp RaModelIn,
                     FTWeightCsharp FTmodelIn,
                     [In, MarshalAs(UnmanagedType.I4)] int strategy,
                     [In, MarshalAs(UnmanagedType.I4)] int rollLifeMaximization,
                     RaInputsCsharp RaDataIn,
                     char Version,
                     [In, MarshalAs(UnmanagedType.R4)] float errMax,
                     [Out, MarshalAs(UnmanagedType.I4)] out int error);

この関数をC#で呼び出すときは、3番目のパラメーターにrefを追加します。

C ++では、関数のシグネチャは変更されません。

extern EXPORTTOTEM_API 
MULTICURVETYPE* DLL_FlesCalculation( struct MultiRollInformation *multiRollInfo,
    struct CoilInformation *coilInfo, 
    struct RollInformation *rollInfo,
    struct LimitsType *LimitsSteel,
    struct LimitsType *LimitsRegulation,
    struct LimitsType *LimitsMachine,
    struct FTInputs *forceTensionInfo,
    struct RaConstants *constRaIn,
    struct FTWeight *modelFTIn,
    int strategy,
    int rollLifeMaximization,
    struct RaInputs *dataRaIn,
    char Version,
    float errMax,
    int &error);   

これにより、DLL_FlesCalculationが呼び出されたときにクラッシュします。

于 2009-07-17T08:49:19.177 に答える