2009-01-14 6 views
2

dans mon application J'ai 2 couches. La première couche est un héritage C exposant des fonctions cdecl qui utilisent la syntaxe "..." pour une liste de paramètres variable. Le seul moyen que j'ai trouvé pour appeler ces fonctions à partir de ma couche .Net (la seconde) utilise les techniques DllImport. Par exemple, la fonction C ci-dessous:Utilisation de __arglist avec un ensemble variable de paramètres nommés

int myFunc(char* name, ...); 

ressemble que C#:

[DllImport("MyDll.dll"), 
CharSet = CharSet.Ansi, 
CallingConvention = CallingConvention.Cdecl] 
int myFunc(string name, __arglist); 

Mon problème est que parfois, je veux appeler cette fonction avec 2 paramètres supplémentaires, mais si l'un d'entre eux est NULL il ne sera pas inclus dans la liste des arguments (mon code hérité échoue sur les valeurs NULL). Par exemple, je veux cet appel:

int foo(string name, string a, string b) 
{ 
    myFunc(name, __arglist(a, b)); 
} 

{ 
    foo("john", "arg1", null); 
} 

à être interprété par C comme

myFunc("john", "arg1"); 

faire Malheureusement quelque chose comme ça:

int foo(string name, string a, string b) 
{ 
    List<string> args = new List<string>(); 
    if(a != null) args.Add(a); 
    if(b != null) args.Add(b); 
    myFunc(name, __arglist(args)); 
} 
{ 
    foo("john", "arg1", null); 
} 

est interprété par C comme ça:

myFunc(name, args); 

et non:

myFunc(name, args[0]); 

Est-ce que quelqu'un a une idée?

Répondre

2

Comment la fonction C sait-elle quel est le dernier paramètre? Il ne peut pas savoir a priori combien de paramètres il y a. Il a besoin d'informations supplémentaires. Une façon courante pour les fonctions d'obtenir les informations dont elles ont besoin est d'analyser le paramètre string inclus pour compter les spécificateurs de format, comme dans printf. Dans ce cas, si la chaîne de format indique seulement qu'il y a un paramètre supplémentaire, alors la fonction ne connaît pas la différence entre un appel qui n'avait vraiment qu'un paramètre supplémentaire et un appel qui en avait deux ou un appel qui en avait 20. La fonction devrait avoir l'autodiscipline pour ne lire qu'un seul paramètre, puisque c'est toute la chaîne de format qu'il y avait. En lire plus conduirait à un comportement indéfini.

Si ce que j'ai décrit n'est pas la façon dont fonctionne votre fonction, alors vous ne pouvez pas faire grand-chose pour résoudre le problème. Mais si est comment fonctionne votre fonction, alors il n'y a rien à faire sur l'appel, car il n'y a pas de problème.

Une autre option, puisque vous indiquez que votre "code hérité échoue sur les valeurs nulles", est de réparer votre ancien code pour qu'il ne tombe plus en panne.

Une troisième option est d'écrire simplement les quatre possibilités:

if (a != null) { 
    if (b != null) 
    return myFunc(name, a, b); 
    else 
    return myFunc(name, a); 
} else { 
    if (b != null) 
    return myFunc(names, b); 
    else 
    return myFunc(names); 
} 

Plus de deux paramètres facultatifs, cependant, et le code commence à devenir difficile à manier.

0

Essayez de convertir votre System.List ToArray() avant de l'emballer dans __arglist

myFunc(name, __arglist(args.ToArray()));

Questions connexes