2012-04-29 10 views
1

structの配列への参照をとり、操作が成功するかどうかを判断するバイトを返す(.dll)ファイルのc関数を使用します。 これはCプロジェクト でうまく動作し、小さなサイズの配列(最大7要素)を送信するとうまくいきました。 とそれ以降は偽です!マーシャリング中の大きなサイズの配列

配列は、あなたがあなたの構造体の8つのバイトをハードコードされているようだ次のstruct

[StructLayout(LayoutKind.Sequential)] 
    public struct MainStruct 
    { 
     [MarshalAsAttribute(UnmanagedType.Struct, SizeConst = 5)] 
     public Struct2 Struct2Object; 

     [MarshalAsAttribute(UnmanagedType.U8, SizeConst = 1)] 
     public UInt64 Elem1; 

     [MarshalAsAttribute(UnmanagedType.U8, SizeConst = 1)] 
     public UInt64 Elem2; 

     [MarshalAsAttribute(UnmanagedType.U8, SizeConst = 1)] 
     public UInt64 Elem3; 

     [MarshalAsAttribute(UnmanagedType.U8, SizeConst = 1)] 
     public UInt64 Elem4; 

     [MarshalAsAttribute(UnmanagedType.U8, SizeConst = 1)] 
     public UInt64 Elem5; 

     [MarshalAsAttribute(UnmanagedType.U8, SizeConst = 1)] 
     public UInt64 Elem6; 

     [MarshalAsAttribute(UnmanagedType.U8, SizeConst = 1)] 
     public UInt64 Elem7; 

     [MarshalAsAttribute(UnmanagedType.U8, SizeConst = 1)] 
     public UInt64 Elem8; 

    }; 
+1

関数のネイティブ定義はどのように見えますか?C#でどのように定義しましたか?ネイティブ関数をデバッグして偽を返すことができますか? – svick

+1

また、 'struct'を埋め込み配列でマーシャリングしたい場合は、配列にSeveraの代わりに' UnamanagedType.ByValArray'を使用できますlフィールド。別の質問:ネイティブ関数が配列の大きさをどのように見つけ出すのでしょうか? – svick

+1

あなたはSizeConstで横たわりをやめなければなりません。 UInt64が1バイトしか持てない場所を考えることはできません。 –

答えて

0

からです。もちろん、あなたが限界を超えた場合、あなたはメモリ破壊を受けるでしょう。

"送信する"バイト数が無制限である場合、私はMarshal.AllocHGlobalを使用してunamanagedバッファを割り当て、アンマネージ機能に渡します。

+0

私は何を言ったか試しました.. MainStruct OBJ =(MainStruct)Marshal.PtrToStructure(pointertostruct、typeof(MainStruct)); ポインタはデータをconatinしますが、オブジェクトをゼロで初期化します!! – Ahmed

+0

あなたはあなたを助けるための十分な情報を与えていないことを理解していますか? – usr

+0

私は: 構造体が以前に表示されました.. 今、私はデータへのポインタを持っていて、それを構造体に変換できません – Ahmed

0
__declspec(dllexport) TU08 GetBuffer(MainStruct *OBJ) 
    { 
    TU64 SelectedOBIS; 
    TU08 XdrBuffer[Dlms_mXdrMaxBuffer]; 
    TU08 *pXdrBuffer; 
    TU32 i; 
    TU32 NumberOfElements; 

    pXdrBuffer = XdrBuffer; 
    SelectedOBIS = ProfilesData[LOG_ID_1].ProfilesOBISCodes; 

     pXdrBuffer = XdrBuffer; 
     Dlms_gXdrInitBuffer(); 
     /////// Get Data /////// 
     if(Main_iSendGetRequest(SelectedOBIS, 7, 2, XdrBuffer) == false) 
      return 0; 
     /////// Extract Data /////// 
     if(*XdrBuffer == Dlms_mXdrArray) 
     { 
      NumberOfElements = *(pXdrBuffer + 1); 
      pXdrBuffer += 2; // 2 for array tag and its number of fields 
      for(i=0; i<NumberOfElements; i++) 
      { 
       if(*pXdrBuffer == Dlms_mXdrStruct) 
       { 
    pXdrBuffer += 2; // 2 for struct tag and its number of fields 
    pXdrBuffer = gGetDateTime(pXdrBuffer, &OBJ[i].TimeStamp); 
    pXdrBuffer = gGetLongUnsigned(pXdrBuffer, &OBJ[i].StatusRegister); 
    pXdrBuffer = gGetUnsigned(pXdrBuffer, &OBJ[i].EventCode); 
    } 
      } 
     } 
    return 1; 
} 

これは、使用される機能です。

と、これはC

typedef struct 
{ 
    Struct2 Struct2OBject; 
    TU64 Elem1; 
    TU64 Elem2; 
    TU64 Elem3; 
    TU64 Elem4; 
    TU64 Elem5; 
    TU64 Elem6; 
    TU64 Elem7; 
    TU64 Elem8; 
} MainStruct; 

で構造体である機能のマーシャルが

[DllImport("dll.dll", CallingConvention = CallingConvention.Cdecl)] 
    public static extern byte GetBuffer([In, Out] MainStruct[] Profile); 

である点は、それがCにうまく機能している場合、あまりにもWindowsフォームアプリケーションに適していますということです関数に渡される配列のサイズは7以下です!

+0

'[MarshalAsAttribute(UnmanagedType.U8、SizeConst = 1) ] '。それは間違っています。 – leppie

0

i`veは:(.. にデータを取得するためにポインタを使用しようと、この時点まで、それは大丈夫動作します。

MainStruct OBJ = (MainStruct)Marshal.PtrToStructure(pointertostruct, typeof(MainStruct)); 

ポインタがデータを取得しますが、それはちょうどゼロでオブジェクトを初期化します! !

関連する問題