J'utilise une DLL native. Je ne suis pas sûr, mais je pense que je ne peux pas utiliser PInvoke avec ça, car il n'exporte aucune fonction et n'a pas de manifeste. La DLL est livrée avec un fichier d'en-tête, expliquant comment l'utiliser. Le fichier d'en-tête définit d'innombrables structs, enums et une classe à construire en utilisant une méthode d'usine qui est accessible via une fonction Windows ::GetProcAddress
(sécurité à travers obscurité). Cette classe contient les fonctions que j'aimerais utiliser dans le code managé.Est-il possible de marshaler matrice tableau natif à un tableau géré avec une boucle for
J'ai réussi à encapsuler la classe dans une classe de référence CLI et à y appeler des méthodes triviales, en les enveloppant également.
Je passe par le processus de conversion de certaines structures du fichier d'en-tête en structures gérées. Par exemple, struct autochtones:
struct FooACL{
int action;
unsigned long from,to;
char comment[64];
int reserved[17];
};
Se transforme en struct géré:
[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;
};
Pour autant que je peux dire cela devrait rendre le blittable struct géré? Et toute autre structure qui suit un modèle similaire ou des niveaux de structure imbriquée. Tant qu'une mise en page est spécifiée et qu'aucun blittable n'est orné de MarshalAs, la structure dans son ensemble sera-t-elle blittable?
Et donc, je tente de voir s'il y a un moyen d'utiliser Marshal::Copy
ou Marshal::PtrToStructure
pour convertir un tableau FooACL*
-array<ManagedFooACL>^
.
Je reçois le tableau FooACL * à partir d'un appel de fonction; Je ne l'attribue pas moi-même.
int total;
FooACL* foos = unamagedClass->GetFooACLS(&total);
total
est une entrée/sortie qui obtient la taille du tableau retourné.
Ce que je réussi à faire jusqu'à présent, et ce travail est:
ManagedFooACL first = static_cast<ManagedFooACL>(Marshal::PtrToStructure(IntPtr(&foos [0]), ManagedFooACL::typeid));
Ce que je ne peux pas envelopper mon esprit est autour de pourquoi cela ne:
array<ManagedFooACL>^ mfoos = gcnew array<ManagedFooACL>(total);
Marshal::PtrToStructure(IntPtr(&foos), mfoos);
Cela jette un: Y at-il un moyen de copier des données de tableau dans un appel ou ai-je vraiment besoin de faire une boucle for? Cela semble un peu idiot avec toute cette capacité de marshaling.
Remarque: Si vous pouvez accéder à la fonction à l'aide de 'GetProcAddress', la fonction est exportée et peut être invoquée via pinvoke. –
Je suis d'accord, mais ce n'est qu'une fonction d'usine qui me donne une classe qui contient la plupart des fonctionnalités que je recherche – Dmitry
Bon, je ne voulais pas dire qu'il est pratique de le faire, juste en le notant pour référence future. :) –