2010-06-21 3 views
4

Je suis assez nouveau pour Interop/Com/ActiveX etc, donc supporter avec moi.C# liaison tardive au serveur com/activeX, problème avec une méthode

Je suis en retard de liaison dans un com/activex (pas sûr lequel) serveur (fondamentalement un exe pas un dll). J'utilise avec succès toutes les méthodes de ce serveur sauf une, voici la description:

VT_INT GetLastCCTError (variante * chaine_erreur);

Description: Cette fonction permet de récupérer la dernière erreur générée par le CCT. La fonction peut être appelée à tout moment tant que le serveur CCT est initialisé. Si aucune erreur n'a survenue lors de l'appel de la fonction, le code renvoyé est '0' (zéro) et la chaîne d'erreur sera vide. Seulement la dernière erreur qui s'est produite pendant l'exécution actuelle du serveur CCT sera être disponible.

entrée: Aucun

sortie: La fonction retourne un paramètre de sortie unique, « ERROR_STRING » de type VARTYPE VT_BSTR | VT_BYREF. Le paramètre contient une chaîne d'erreur associée au code d'erreur associé à la dernière défaillance de la fonction CCT . Valeur de retour: Cette fonction renvoie une valeur entière de type VT_INT. Ceci est le code d'erreur associée à la dernière fonction CCT échec

J'ai d'abord essayé d'utiliser ce code:

this.LastErrorCode = (int)CCTType.InvokeMember("GetLastCCTError", BindingFlags.InvokeMethod, null, CCTObject, new object[] {this.LastErrorString}); 

Je suis l'exception suivante: Exception de HRESULT: 0x80020005 (DISP_E_TYPEMISMATCH)

Puis après réflexion j'ai changé le code:

object[] Args = { "SomeString" }; 

this.LastErrorCode = (int)CCTType.InvokeMember("GetLastCCTError", BindingFlags.InvokeMethod, null, CCTObject, Args); 

Toujours la même erreur. Après quelques recherches sur Google, je trouve cet article: http://www.informit.com/articles/article.aspx?p=27219&seqNum=8

Si vous regardez la section 3.3, il semble être la solution à mon problème, et donc je l'ai changé mon code pour:

object[] Args = { "SomeString" }; 

ParameterModifier ParMod = new ParameterModifier(1); 
ParMod[0] = true; 
ParameterModifier[] ArrParMod = { ParMod }; 

this.LastErrorCode = (int)CCTType.InvokeMember("GetLastCCTError", BindingFlags.InvokeMethod, null, CCTObject, Args, ArrParMod, null, null); 

this.LastErrorString = (string) Args[0]; 

Il en résulte encore dans le même exception. Je pense maintenant que le problème n'est peut-être pas la référence mais quelque chose d'autre. Toute aide serait appréciée.

+0

Juste pour cause d'intérêt. J'ai essayé d'appeler la méthode en VB et il fonctionne avec le code suivant: Dim CCTObject As Object CCTObject = CreateObject ("CCTServer.Document") Dim result = CCTObject.InitializeDevice ("Caméra") Dim ms As String Résultat = CCTObject.GetLastCCTError (ms) – Roelf

Répondre

0

Cela fait longtemps que je n'ai pas fait de travail d'interopérabilité, mais avez-vous envisagé d'utiliser un StringBuilder? Voir receiving strings through interop pour un exemple.

espérons que cette aide,

Andrew

1

Est-ce parce que les chaînes en C# sont immuables."SomeString" sera résolu par le compilateur en tant que chaîne non modifiable sur la mémoire gérée (la pile ou le segment de mémoire est en grande partie hors de propos dans votre cas). Donc, d'une certaine manière, vous ne passez pas une référence de chaîne mais un littéral - quelque chose qui ne pourrait jamais être un paramètre 'out' comme dans votre exemple ... donc le marshalling ne fera pas ce qu'il pense (sait) serait une mauvaise idée. Andrew D, je suppose, a raison.

pourrait donner à penser que vous essayez quelque chose comme:

StringBuilder errorMessage = new StringBuilder(); 

this.LastErrorCode = (int)CCTType.InvokeMember("GetLastCCTError", BindingFlags.InvokeMethod, null, CCTObject, errorMessage); 

this.LastErrorString = errorMessage.ToString(); 

Cordialement,

Aidanapword

Questions connexes