6

ネイティブDLLを使用しています。よくわかりませんが、PInvoke declは関数をエクスポートせず、マニフェストがないため、使用できないと思います。DLLは、その使用方法を説明するヘッダーファイルとともに提供されます。::GetProcAddressヘッダーファイルは、Windows関数(隠すことによるセキュリティ)を介してアクセスされるファクトリメソッドを使用して構築される無数の構造体、列挙型、および1つのクラスを定義します。このクラスには、マネージコードで使用したい関数が含まれています。

クラスをCLIrefクラスで正常にラップし、そのクラスで簡単なメソッドを呼び出して、それらもラップすることができます。

いくつかの構造体をヘッダーファイルから管理構造体に変換するプロセスを実行しています。たとえば、ネイティブ構造体:

struct FooACL{
    int               action;                
    unsigned long     from,to;               
    char              comment[64]; 
    int               reserved[17];          
};

管理構造体に変わります:

[StructLayout(LayoutKind::Sequential, CharSet = CharSet::Ansi)]
public value struct ManagedFooACL{
     int   action;                
     int   from,to;     
     [MarshalAs(UnmanagedType::ByValTStr, SizeConst = 64)]
     String^    comment;
     [MarshalAs(UnmanagedType::ByValArray, SizeConst = 17)]
     array<int>^ reserved;
};

私が知る限り、これは管理された構造体をblittableにする必要がありますか?そして、ネストされた構造の同様のパターンまたはレベルに従う他の構造体。レイアウトが指定されていて、MarshalAsで装飾されているブリット可能なものがない限り、構造全体がブリット可能になりますか?

そのため、配列を使用Marshal::CopyまたはMarshal::PtrToStructure変換する方法があるかどうかを確認しようとしています。FooACL*array<ManagedFooACL>^

関数呼び出しからFooACL*配列を取得します。私はそれを自分で割り当てません。

int total;
FooACL* foos = unamagedClass->GetFooACLS(&total);

total返される配列のサイズを取得するin/outです。

私がこれまでに何とかしたこと、そして仕事は何ですか:

ManagedFooACL first = static_cast<ManagedFooACL>(Marshal::PtrToStructure(IntPtr(&foos [0]), ManagedFooACL::typeid));

私が頭を悩ませることができないのは、なぜこれができないのかということです。

array<ManagedFooACL>^ mfoos = gcnew array<ManagedFooACL>(total);
Marshal::PtrToStructure(IntPtr(&foos), mfoos);

これは以下をスローします:

System.ArgumentException was unhandled
  Message=The specified structure must be blittable or have layout information.
Parameter name: structure
  Source=mscorlib
  ParamName=structure

1回の呼び出しで配列データをコピーする方法はありますか?それとも本当にforループを実行する必要がありますか?このすべてのマーシャリング機能を使用すると、ちょっとばかげているようです。

4

1 に答える 1

3

さらに調査を行った結果、答えはノーのようです。ループせずにan arrayofを自動マーシャリングすることはできません。struct

structマーシャリングが機能する主な理由PtrToStructureは、構造が静的/事前定義されているためだと思います。コンパイラは、メモリのレイアウト方法を認識しています。動的サイズを取得するため、array事前にメモリ レイアウトを指定する方法はありません。structしたがって、動的な数のsをループする必要があります。

または、常に X の長さの配列を取得することがわかっている場合は、struct1 つの要素を保持する独自のマネージを定義できます。つまり、 の配列とXの値をManagedFooACL持ち、ネイティブを にキャストするだけです。ByValArraySizeConstarraystruct

于 2013-01-02T22:12:24.243 に答える