J'ai une méthode C++ avec cette signature:Invoke C++ méthode de VB.Net avec chaîne traitée comme tableau de chaînes
STDMETHODIMP ClassName::FunctionName(long number, BSTR* names, long* status)
Dans la méthode la variable noms est accessible comme un tableau de chaînes, à savoir
char * tempString = NULL;
for (int n = 0; n < number; n++)
{
tempString = OLE2T(names[n]);
...
Je compile le projet C++, qui génère une DLL, puis j'inscris cette DLL et j'y ajoute une référence dans le projet VB. Lorsque j'ajoute la référence, un ensemble Interop est généré automatiquement, et la signature de la méthode dans l'assemblage Interop est la suivante:
FunctionName (number as Integer, ByRef names as String) As Integer
De VB.Net j'invoque la méthode comme ceci:
result = FunctionName (number, names(0))
Où noms est un tableau de chaînes avec plusieurs éléments, et le nombre et le résultat sont des entiers. Le problème est que lorsque le code C++ tente d'accéder au reste des éléments dans le tableau de noms (noms [1] et à venir) il commence à obtenir "garbage" sur ces champs.
Ma question est, comment puis-je envoyer le tableau de chaînes entières au lieu de seulement la première valeur.
Le code C++ est une bibliothèque que je ne peux pas modifier, donc tout changement que je fais doit être sur le code VB.Net.
Je pensais que peut-être utiliser PInvoke pour appeler la méthode pourrait faire l'affaire (en déclarant une signature correcte), mais j'espérais quelque chose de mieux.
Des idées?
Merci!
Edit:
Je ne suis pas expert en Interop/Marshaling mais j'ai vérifié la définition IDL de la méthode et se présente comme suit:
[id(60), helpstring("method FunctionName")]
HRESULT FunctionName(
[in] long number,
[in, size_is(number)] BSTR* names,
[out, retval] long* status);
devrait-il pas size_is indiquer que les noms paramètre est un tableau, et donc, lorsque l'assembly Interop est généré agir en conséquence?
Merci encore
Vous avez besoin de directives IDL spéciales pour indiquer au marshaller COM que 'number' correspond à la taille du tableau de chaînes' names'. Sinon, le marshaller ne le sait pas, et attend simplement des valeurs indépendantes, sans savoir que 'names' est un tableau du tout. Bien sûr, vous pouvez écrire un wrapper C++, qui "connaît" le comportement incorrect de la bibliothèque C++ d'origine, et corrige l'interface. – gimpf
Merci pour votre réponse rapide, je viens d'éditer la question avec ce que je pense est l'information idl requis comme vous le dites. Aucun conseil? – willvv
VB n'a pas p/invoke ou 'MarshalAsAttribute', peut-être que vous vouliez dire VB.net? Et 'names [0]' n'est pas la syntaxe de l'élément de tableau dans VB non plus? Le moyen le plus propre de résoudre votre problème serait avec un encapsuleur C++/CLI qui accepte un .NET 'array', convertit en un tableau de 'BSTR', puis appelle la fonction C++. –