2016-02-27 1 views
0

Je tente de charger et d'exécuter un exécutable dotnet à partir d'un tampon de mémoire dans mon programme C++.L'appel de la méthode d'assemblage dotnet à partir de C++ renvoie une erreur COR_E_SAFEARRAYTYPEMISMATCH

Pour ce faire, j'essaie d'invoquer la fonction Main d'un assemblage dotnet que j'ai chargé dans mon projet C++.

D'abord, je charge l'exécution CRL, est chargé ok.

Ensuite, je charge le dotnet.exe à partir d'un tampon de mémoire, il est chargé ok.

Ensuite, je voudrais le démarrer, en invoquant sa fonction principale.

À ce stade, la fonction Invoke_3 renvoie COR_E_SAFEARRAYTYPEMISMATCH. Ce que je ne comprends pas pourquoi, puisque j'ai récupéré les paramètres en utilisant la fonction GetParameters, qui remplit le SAFEARRAY pour passer à la fonction Invoke. Quelqu'un sait ce qui ne va pas dans ces paramètres? Merci d'avance!

// Up here we correctly load the CRL runtime 

// Load up our dotnet file inside a std::string 
string sFileData = FileToString("C:\\dotnet.exe"); 

// Copy our file data inside a SAFEARRAY 
SAFEARRAYBOUND bounds = { sFileData.size(), 0 }; 
SAFEARRAY *pSA = SafeArrayCreate(VT_UI1, 1, &bounds); 
void* data; 
HRESULT hr = SafeArrayAccessData(pSA, &data); 
CopyMemory(data, sFileData.c_str(), sFileData.size()); 
hr = SafeArrayUnaccessData(pSA); 

if (pSA) 
{ 
    // Load our managed assembly: 
    _AssemblyPtr spAssembly = nullptr; 
    hr = spAppDomain->Load_3(pSA, &spAssembly); 

    // Get the entrypoint of the assembly, which should be the "Main" function 
    _MethodInfoPtr entryp; 
    hr = spAssembly->get_EntryPoint(&entryp); 

    // Get the parameters of the entrypoint function and save them in a SAFEARRAY 
    SAFEARRAY *pArrParams; 
    hr = entryp->GetParameters(&pArrParams); 

    // Call the entrypoint passing parameters in the SAFEARRAY. 
    // Returns error COR_E_SAFEARRAYTYPEMISMATCH 
    VARIANT retval; 
    hr = entryp->Invoke_3(_variant_t(), pArrParams, &retval); 
} 
+1

Une méthode Main() a normalement un argument de chaîne []. Vous ne passez pas un tableau de chaînes, en passant ParameterInfo [] est bien sûr condamné à échouer. Vous avez besoin d'un tableau sécurisé de BSTR. –

+0

Mais, la fonction entryp-> GetParameters (& pArrParams) ne devrait-elle pas remplir automatiquement le SAFEARRAY avec les paramètres corrects de la méthode entryp que nous invoquerons plus tard? Que se passe-t-il si la fonction principale dotnet a des paramètres différents à la place? Merci – Flavio

+1

Il vous parle du * type * des arguments. Si ce n'est pas string [] alors vous devriez vous plaindre. Eh bien, pas besoin d'aider comme vous l'avez découvert. Passer la * valeur * des arguments est à vous. –

Répondre

0

Selon le framework source for SafeArrayTypeMismatchException (qui mappe COR_E_SAFEARRAYTYPEMISMATCH):

Cette exception est levée lorsque le type d'exécution d'un tableau est différent de celui du sous-type de tableau sécurisé spécifié dans les métadonnées.

Par conséquent, je suis sûr que c'est le problème:

SafeArrayCreate(VT_UI1, 1, &bounds); 

VT_UI1 est un entier non signé 1 octet. Mais la méthode standard Main() dans les applications C# prend un tableau d'entiers signés de 4 octets. Ce sont des types différents, d'où l'erreur. Donc, vous devrez changer votre code à ceci:

SafeArrayCreate(VT_I4, 1, &bounds); 
+0

Merci pour votre réponse, cependant, cette fonction n'est pas utilisée dans la fonction Invoke. Ce tableau est utilisé dans 'hr = spAppDomain-> Load_3 (pSA, & spAssembly);' fonction, qui charge l'assemblage bien. La fonction Invoke_3 qui renvoie l'erreur utilise à la place le SAFEARRAY rempli par entryp-> GetParameters (& pArrParams); J'ai essayé de le changer quand même pour voir s'il y avait une différence, mais si j'utilise VT_I4, la fonction Load_3 échouera. – Flavio