Conserver une référence d'une dll c++ native jusqu'à couche C#

Résolu
dodo7263 Messages postés 616 Date d'inscription mercredi 10 septembre 2008 Statut Membre Dernière intervention 9 février 2017 - 16 sept. 2016 à 15:47
dodo7263 Messages postés 616 Date d'inscription mercredi 10 septembre 2008 Statut Membre Dernière intervention 9 février 2017 - 19 sept. 2016 à 16:01
Bonjour à tous,
Je vais essayer d'être le plus clair possible.
J'ai écris une DLL native qui contient 1 méthode effectuant tout un tas de calcul. jusque la tout va bien.


double SpectralPropertySoil(double slope, double snow,double snowage, double IN_thetas, double thetassat, double &OUT_reflvs, double &OUT_reflns,double ksnow, double reflvsground, double reflvssnowfresh, double reflvssnowold,double reflnsdry, double reflnsmoist, double reflnssnowfresh, double reflnssnowold) { some calculations...}

Notez les 2 références que je souhaite récupérer en C# !
J'ai donc rajouté un projet C++/CLI dans lequel je référence cette DLL native et je "wrapp" cette fonction dans une public ref class comme ceci :
Le fichier.h:

double SpectralPropertySoilWrapped( double slope, double snow,double snowage, double IN_thetas, double thetassat, double OUT_reflvs, double OUT_reflns,double ksnow, double reflvsground, double reflvssnowfresh, double reflvssnowold,double reflnsdry, double reflnsmoist, double reflnssnowfresh, double reflnssnowold);

Le fichier.cpp:

double CompleteWrapper::SpectralPropertySoilWrapped( double slope, double snow,
double snowage, double IN_thetas, double thetassat, double OUT_reflvs, double OUT_reflns,
double ksnow, double reflvsground, double reflvssnowfresh, double reflvssnowold,
double reflnsdry, double reflnsmoist, double reflnssnowfresh, double reflnssnowold)
{ return PasimWrapper::SpectralPropertySoil(slope, snow, snowage, IN_thetas, thetassat, OUT_reflvs,OUT_reflns, ksnow, reflvsground, reflvssnowfresh, reflvssnowold, reflnsdry, reflnsmoist, reflnssnowfresh, reflnssnowold);
}

et enfin mon projet C# qui utilise cette DLL. Le tout fonctionne à peu près bien car je n'arrive pas à récupérer les 2 valeurs référencées en natif (&). J'ai essayé des choses avec des pointeurs, des tracking reference, etc...mais je crois que j'ai besoin d'un oeil extérieur maintenant. Les valeurs sont conservées jusqu'à la couche C++/CLI et au moment ou le programme retourne dans le C# les références sont perdues.
Auriez vous une piste ? une indication ? ou peut être je fais mal les choses avec mon code ?
Dites moi car la je dois dire que je suis à court d'idées.
Merci !
@pluche

3 réponses

Whismeril Messages postés 18641 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 3 octobre 2023 629
17 sept. 2016 à 09:27
Bonjour

je te livre la réponse d'un de mes collègues trop timide pour venir poster lui même

faut qu'il mette

double % mareference

dans la déclaration de la fonction, le % étant l'équivalent CLI du & natif, et du ref en C#.

0
dodo7263 Messages postés 616 Date d'inscription mercredi 10 septembre 2008 Statut Membre Dernière intervention 9 février 2017 6
18 sept. 2016 à 15:23
Bonjour wishmeril,

Malheureusement j'ai bien essayé cela. Je sais que % est l'équivalent du & avec du ref en C#. Mais lorsque je fais cela j'ai toujours l'erreur suivante :
a simple (non tracking) reference cannot be bound to an entity on the managed heap.

Non je suis vraiment à cours d'idées. C'est un peu pour ça que je poste mon soucis.

Quand je ne met aucune référence, cela fonctionne parfaitement bien. mais dès lors que je veux récupérer ces 2 références c'est la que commence les problèmes. J'ai essayé en déclarant un pointeur dans la couche CLI vers ma classe native mais la j'ai un soucis de conversion de double en double*.

Merci de ta réponse ;-)

S.D
0
dodo7263 Messages postés 616 Date d'inscription mercredi 10 septembre 2008 Statut Membre Dernière intervention 9 février 2017 6
19 sept. 2016 à 16:01
Re tous,

Bon avec un peu d'aide voici la solution : Il me fallait passer par des copies de variables. Faire une couche C++/CLI un peu plus élaborée :


double CompleteWrapper::SpectralPropertySoilWrapped( double slope, double snow,
double snowage, double IN_thetas, double thetassat, double %OUT_reflvs, double %OUT_reflns,
double ksnow, double reflvsground, double reflvssnowfresh, double reflvssnowold,
double reflnsdry, double reflnsmoist, double reflnssnowfresh, double reflnssnowold)
{
double copy_reflvs = OUT_reflvs;
double copy_reflns = OUT_reflns;
double ret = PasimWrapper::SpectralPropertySoil(slope, snow, snowage, IN_thetas, thetassat, copy_reflvs, copy_reflns, ksnow, reflvsground, reflvssnowfresh, reflvssnowold, reflnsdry, reflnsmoist, reflnssnowfresh, reflnssnowold);
OUT_reflvs = copy_reflvs;
OUT_reflns = copy_reflns;
return ret;
}


Merci à ceux qui ont pris le temps de lire. En espérant que cette solution puisse servir à d'autres. Allez hop--> résolu

@pluche

SD
0
Rejoignez-nous