ネイティブ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ループを実行する必要がありますか?このすべてのマーシャリング機能を使用すると、ちょっとばかげているようです。