cs_RMI
Messages postés305Date d'inscriptionvendredi 18 juillet 2003StatutMembreDernière intervention 2 août 2010
-
6 août 2007 à 15:59
cs_Corolle
Messages postés2Date d'inscriptionvendredi 9 février 2007StatutMembreDernière intervention13 août 2007
-
13 août 2007 à 19:52
Bonjour,
J'utilise une dll écrite en C++ et je n'arrive pas à exporter les fonction contenant des variables ayant pour type string
exp:
dans le .H
bool MvaSensor::setCalibPath, (, string , newpath, )
Voilà ce que l'on voit avec Dependency Walker
bool MvaSensor::setCalibPath(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)
et en non décorée
?setCalibPath@MvaSensor@@QAE_NV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z
private
static
extern
bool SetCalibPath(
IntPtr _iPtr,
string _sCalibPath);
mais j'ai l'erreur
System.Acces.Violation
Tentative de lecture ou d'écriture de mémoire protégée. Cela indique souvent qu'une autre mémoire est endommagée.
J'ai aussi essayé avec un StringBuilder mais j'ai toujours le même problème.
Quelqu'un sait-il comment exporter cette !! de fonction ?
Lutinore
Messages postés3246Date d'inscriptionlundi 25 avril 2005StatutMembreDernière intervention27 octobre 201241 6 août 2007 à 21:07
Salut,
Le type string n'existe pas en C/C++ ton prototype utilise un template, c'est l'équivalent des génériques en C#, tu ne pourras pas marshaller le paramêtre en string ou en StringBuilder.
Je ne sais pas comment appeller cette fonction, j'ai jamais été confronté à ce genre de problème.. et je ne maîtrise pas les templates. La convention ThisCall est utile quand tu appeles la fonction d'une classe non-managée mais faut-il encore possèder un pointeur sur cette classe.
EntryPoint peut indiquer le numéro de la fonction c'est plus simple parfois que les noms décorés.
ctx_man
Messages postés285Date d'inscriptionmardi 28 décembre 2004StatutMembreDernière intervention20 janvier 20133 7 août 2007 à 09:30
Salut !
Je n'ai jamais eu ce genre de problèmes à résoudre et je ne peux donc pas t'indiquer ton erreur avec certitude.
Cependant, tu as écrit :
dans le .H
bool MvaSensor::setCalibPath(string newpath)
Ce qui semble indiquer que ta fonction setCalibPath n'est pas statique et fait partie d'un objet qu'il te faudra instancier.
Donc, selon moi, tu devrais tenter d'instancier un objet de la classe MvaSensor, et d'utiliser la méthode associée.
Je n'en suis pas certain non plus, mais utiliser du code non managé dans du code managé n'est permis que dans un contexte unsafe. Tu devras probablement effecuer ce changement de contexte.
Le travail c'est la santé, ne rien faire c'est la préservé !!!
ctx_man
Messages postés285Date d'inscriptionmardi 28 décembre 2004StatutMembreDernière intervention20 janvier 20133 7 août 2007 à 09:33
Arff, Opéra est vraiment mal prit en compte sur ce site. C'est la misère d'écrire une réponse sans faire des erreurs dans la mise en forme.
(Dites les admins ? vous pourriez pas au moins agrandir la texbox ? Parce que la, elle est toute petite, c'est trop la lutte de structurer son HTML la dedans)
Le travail c'est la santé, ne rien faire c'est la préservé !!!
Vous n’avez pas trouvé la réponse que vous recherchez ?
ctx_man
Messages postés285Date d'inscriptionmardi 28 décembre 2004StatutMembreDernière intervention20 janvier 20133 7 août 2007 à 10:06
Lol ouais ! Je sais que j'ai une faute d'orthographe ! Mais je l'aime m'a faute ! Bon d'accord je corrige :'(
Concernant le contexte je suis pas sur de t'avoir compris mais c'est pas un drame.
Et qu'en est-il de ma remarque sur l'instanciation d'un objet MvaSensor ? Encore une fois, je ne fait que lancer des idées, je n'ai jamais été confronté à ce genre de problème.
Le travail c'est la santé, ne rien faire c'est la préserver !!!
leprov
Messages postés1160Date d'inscriptionvendredi 23 juillet 2004StatutMembreDernière intervention21 octobre 201017 7 août 2007 à 10:11
théoriquement, si cest générique, ca ne lest que dans le header et le .lib, je crois(une fois compilé et linké, on a une version de la méthode par type utilisé).
En bref, si tu connais le type dans lequel ton generic est instancié réellement lors de ton appel, cest ce type que tu dois marshaller. Au pire si tu n'y arrive pas, fait une dll C++ dans laquelle tu wrap cet objet, afin de t'éviter la généricité....C'est pas super propre, mais avec un marshalling générique, bon courage (d'ailleurs si meme lutinore seche sur un problème de DllImport, ou va le monde?) :D
Pour un programmeur en langage objet, la lutte des classes c'est tous les jours.
cs_RMI
Messages postés305Date d'inscriptionvendredi 18 juillet 2003StatutMembreDernière intervention 2 août 20102 7 août 2007 à 10:21
Je ne connais rien au C++ et faire un wrapper je te dis pas l'ambiance....
Pour l'instant je pleure et j'implore aussi le fourniseur de ma dll de me donner des fonctions avec des appels avec des types courrants.
leprov
Messages postés1160Date d'inscriptionvendredi 23 juillet 2004StatutMembreDernière intervention21 octobre 201017 7 août 2007 à 10:41
faire un wrapper ca veut juste dire écrire une fonction qui appelle la fonction qui tembete, mais avec une signature différente (comprendre "qui t'arrange").
En bref, tu crée une dll en C++ qui exporte une classe qui exporte les méthode de MvaSensor en faisant un truc du type :
La tas une classe MvaSensor2 qui est dite classe wrapper de MvaSensor car elle a un membre de type MvaSensor et exporte les traitements de MvaSensor mais de manière différente.
Evidemment faudra que tu remplace T1 et T2 par les bons types....et je sais pas si un cast est possible, faut ptetre faire des opérations plus compliqués, ca cest une question a poser sur un forum C++. En tous cas pour marshaller en C# je te conseille de partir sur un truc comme ca....
Lutinore
Messages postés3246Date d'inscriptionlundi 25 avril 2005StatutMembreDernière intervention27 octobre 201241 7 août 2007 à 15:48
Leprov > Merci pour la gentille remarque.
RMI > je suis en train de regarder à quoi correspond std:string en mémoire, ça semble possible de le passer en tableau de byte, je te tiens au courant si je trouve.
cs_RMI
Messages postés305Date d'inscriptionvendredi 18 juillet 2003StatutMembreDernière intervention 2 août 20102 7 août 2007 à 16:46
Merci à tous pour votre participation, mais j'ai réussi a ce que mon fournisseur de dll change le type d'appel de std::string en char *
J'essaierai tout de même la solution de Lutinore, mais je ne comprends pas trés bien la syntaxe
[
return: MarshalAs( UnmanagedType.U1 )
]
si tu pouvais m'expliquer celà STP
Lutinore
Messages postés3246Date d'inscriptionlundi 25 avril 2005StatutMembreDernière intervention27 octobre 201241 7 août 2007 à 17:13
Le type BOOL ( majuscule ) du C est sur 4 bytes, le type bool ( minuscule ) du C++ est sur 1 byte.. par défaut le marshaling C# est sur 4 bytes, donc là j'indique au marshaleur que mon type de retour ne fait que 1 byte.
cs_Corolle
Messages postés2Date d'inscriptionvendredi 9 février 2007StatutMembreDernière intervention13 août 2007 13 août 2007 à 01:42
Bonsoir,
J'ai eu le même problème (string à passer dans une dllimport), je l'ai réglé par un byte *, qui est homogère à du char * en c++ ANSI 8bits
ex:
[
Lutinore
Messages postés3246Date d'inscriptionlundi 25 avril 2005StatutMembreDernière intervention27 octobre 201241 13 août 2007 à 19:32
Il existe plusieurs façon de passer une chaine via DllImport, qu'elle soit ANSI sur 8 bits ou UNICODE sur 16 bits, inutile d'utiliser du code unsafe pour ça.
Comme je l'ai dit plus haut vu qu'il est peut être possible que ça marche avec un tableau de bytes, ça peut marcher aussi avec un pointeur byte*, c'est pour ça que j'ai proposé un exemple avec Marshal.StringToHGlobalAnsi, ça fait la même chose en évitant le code unsafe.
cs_Corolle
Messages postés2Date d'inscriptionvendredi 9 février 2007StatutMembreDernière intervention13 août 2007 13 août 2007 à 19:52
J'ai découvert sur le net hier soir une solution très propre qui utilise les wrapper, en prime c'est très simple et très bien expliquée.
http://www.supinfo-projects.com/fr/2005/wrapper_dotnet_fr/ Bonne lecture, ça vaut vraiment le détour, et en plus ça marche....
-Corolle