Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

char** nach va_list

8 views
Skip to first unread message

Matthias Friedrich

unread,
Dec 3, 2008, 6:35:45 PM12/3/08
to
Hallo NG,

ist es möglich ein char** in eine va_list zu packen, sodass diese als
Ellipsis-Parameter übergeben werden kann?

Hintergrund: ich habe eine Methode in einer DLL, die ich in .NET/C# nutzen
möchte, die einen Ellipsis-Parameter aufweist; diesen kann ich aus C# heraus
nicht in geeigneter Weise marshallen. Deshalb habe ich mir überlegt die
Methode in eine eigene C-DLL auszulagern, dieser Methode, die Argumente als
char** zu übergeben und als va_list an die eigentliche DLL weiterleiten.

Vielen Dank,
Matthias

Martin Richter [MVP]

unread,
Dec 4, 2008, 4:26:07 AM12/4/08
to
Hallo Matthias!

> ist es möglich ein char** in eine va_list zu packen, sodass diese als
> Ellipsis-Parameter übergeben werden kann?

Eine va_list ist kein Ersatz für Ellipse.
Man kann aus einer va_list keine Ellipse machen.

> Hintergrund: ich habe eine Methode in einer DLL, die ich in .NET/C#
> nutzen möchte, die einen Ellipsis-Parameter aufweist; diesen kann ich
> aus C# heraus nicht in geeigneter Weise marshallen.

Und eine Ellipse in C#? Gint es das?
Zumindest ist etwas ganz anderes als in C++. Oder meinst Du C++/CLI?

> Deshalb habe ich mir
> überlegt die Methode in eine eigene C-DLL auszulagern, dieser Methode,
> die Argumente als char** zu übergeben und als va_list an die eigentliche
> DLL weiterleiten.

IMHO ist es dort ein Array von Objekten/Werten....
public static void UseVariableParameters(params int[] list)

Versuche Dein Problem noch mal anders zu schildern.

--
Martin Richter [MVP] WWJD http://blog.m-ri.de
"A well-written program is its own heaven; a poorly written
program is its own hell!" The Tao of Programming
FAQ: http://www.mpdvc.de Samples: http://www.codeproject.com

Matthias Friedrich

unread,
Dec 4, 2008, 6:53:01 AM12/4/08
to
Hallo Martin,

Antworten siehe unten im Kontext...

Danke und Gruss,
Matthias

"Martin Richter [MVP]" wrote:

> Hallo Matthias!
>
> > ist es möglich ein char** in eine va_list zu packen, sodass diese als
> > Ellipsis-Parameter übergeben werden kann?
>
> Eine va_list ist kein Ersatz für Ellipse.
> Man kann aus einer va_list keine Ellipse machen.
>

Habe ich zuerst angenommen; ich versuche meinen Gedankengang, der mich zu
dieser Annahme führte mal am Beispiel von fprintf und Console.WriteLine zu
erklären.

fprintf(char* format, ...);

Das kann im Code bekanntermaßen so aufgerufen werden:
fprintf("Zwei Zahlen: %i, %i", 11, 23);

Die WriteLine-Methode in C# sieht so aus...
WriteLine(string format, params object[] args);

Und kann in gleicher Weise verwendet werden:
Console.WriteLine("Zwei Zahlen: {0}, {1}", 11, 23);

Oder aber auch so:
object[] zahlen = new object[] { 11, 23 };
Console.WriteLine("Zwei Zahlen: {0}, {1}", zahlen);

Falls das jetzt angenommen wird: Ich weiß, dass Console.WriteLine nicht
fprintf per Invoke aufruft.

> > Hintergrund: ich habe eine Methode in einer DLL, die ich in .NET/C#
> > nutzen möchte, die einen Ellipsis-Parameter aufweist; diesen kann ich
> > aus C# heraus nicht in geeigneter Weise marshallen.
>
> Und eine Ellipse in C#? Gint es das?
> Zumindest ist etwas ganz anderes als in C++. Oder meinst Du C++/CLI?
>

Die Funktion die ich per DLLImport in C# einbinden möchte, hat folgende
Signatur:
int* func(int* , char*, ... );
Wobei die Ellipsis-Parameter laut Doku ebenfalls char* sein sollen.

Den Import habe ich dann so gestrickt...
static extern func(IntPtr, string, params string[] args);

Im ersten Moment sah es gut aus; kein Laufzeitfehler; und Aufrufe an diese
Methode ohne Parameter sondern mit "null" funktionieren tadellos. Der Aufruf
der Methode mit variablen Argumenten klappt auch, allerdings erhalte ich von
der anprogrammierten DLL die Meldung, dass erwartete Argumente nicht
übergeben wurden. Ergo: "params string[] args" klappt nicht.

Meine Idee dazu ist folgende: habe schnell eine eigene C-DLL angelegt
(entsprechende Libs/Header hinzugefügt) und folgende Methode exportiert.

int* myfunc(int* p, char* s, char** args)
{
// hier hätte ich gern aus char** ein va_list gebastelt

va_list val ... // ???

return func(p, s, val);

Martin Richter [MVP]

unread,
Dec 5, 2008, 4:19:17 AM12/5/08
to
Hallo Matthias!

> Die Funktion die ich per DLLImport in C# einbinden möchte, hat folgende
> Signatur:
> int* func(int* , char*, ... );
> Wobei die Ellipsis-Parameter laut Doku ebenfalls char* sein sollen.
>
> Den Import habe ich dann so gestrickt...
> static extern func(IntPtr, string, params string[] args);
>
> Im ersten Moment sah es gut aus; kein Laufzeitfehler; und Aufrufe an diese
> Methode ohne Parameter sondern mit "null" funktionieren tadellos. Der Aufruf
> der Methode mit variablen Argumenten klappt auch, allerdings erhalte ich von
> der anprogrammierten DLL die Meldung, dass erwartete Argumente nicht
> übergeben wurden. Ergo: "params string[] args" klappt nicht.
>
> Meine Idee dazu ist folgende: habe schnell eine eigene C-DLL angelegt
> (entsprechende Libs/Header hinzugefügt) und folgende Methode exportiert.
>
> int* myfunc(int* p, char* s, char** args)
> {
> // hier hätte ich gern aus char** ein va_list gebastelt
>
> va_list val ... // ???
>
> return func(p, s, val);
> }

Das kann nicht gehen. Beim Marshalling müsste bekannt sein wieviele
Argumente vorhanden sind. Das weiß man aber bei der Verwednung von
va_list nicht! ie Anzahl der Argumente wird ja durch die Maske
vorherbestimmt!

va_list selbst ist nur ein Zeiger und keine Struktur oder gar ein Array.
Das Ding übernimmt nur den Zeiger auf den Stack. Man kopiert somit auch
keine Argumente wenn man eine va_list kopiert.

HTH

Matthias Friedrich

unread,
Dec 8, 2008, 9:13:00 AM12/8/08
to
Hallo Martin,

"Martin Richter [MVP]" wrote:

> >
> > int* myfunc(int* p, char* s, char** args)
> > {
> > // hier hätte ich gern aus char** ein va_list gebastelt
> >
> > va_list val ... // ???
> >
> > return func(p, s, val);
> > }
>
> Das kann nicht gehen. Beim Marshalling müsste bekannt sein wieviele
> Argumente vorhanden sind. Das weiß man aber bei der Verwednung von
> va_list nicht! ie Anzahl der Argumente wird ja durch die Maske
> vorherbestimmt!

Ich denke nicht, dass die Maske "analysiert" wird, um die Anzahl der
Argumente zu bestimmen... dafür gibt es sicher ein Macro in vargs.h.

>
> va_list selbst ist nur ein Zeiger und keine Struktur oder gar ein Array.
> Das Ding übernimmt nur den Zeiger auf den Stack. Man kopiert somit auch
> keine Argumente wenn man eine va_list kopiert.
>

Nur aus Interesse: Könnte man den Stack manipulieren um argumente dynamisch
hineinzumogeln?

Martin Richter [MVP]

unread,
Dec 8, 2008, 9:33:49 AM12/8/08
to
Hallo Matthias!


> Nur aus Interesse: Könnte man den Stack manipulieren um argumente dynamisch
> hineinzumogeln?

Wie bitte das? Der Stack wächst von Oben nach unten. Und es ist ein
Stack! Keine Liste!
Wenn also Deine Funktion aufgerufen wird, dann liegen die Stackdaten um
die es Dir geht über Deinen Daten. Darunter kommt der Stackframe Deiner
aktuellen Funktion.

Matthias Friedrich

unread,
Dec 8, 2008, 11:31:01 AM12/8/08
to
Hallo Martin,

mach dich mal locker :-) und versuche mal fünf Minuten über den Tellerrand
zu schauen. Wenn ich dich richtig verstehe, liegen die Daten der aufgerufenen
Funktion jeweils über selben; dann würde ich schlussfolgern, dass man den
Stack der aufzurufenden Funktion zuvor "konstruieren" könnte, oder? Obgleich
es sinnvoll ist, oder nicht.

Gruss, Matthias

Martin Richter [MVP]

unread,
Dec 9, 2008, 2:18:48 AM12/9/08
to
Hallo Matthias !

> mach dich mal locker :-) und versuche mal fünf Minuten über den Tellerrand
> zu schauen. Wenn ich dich richtig verstehe, liegen die Daten der aufgerufenen
> Funktion jeweils über selben; dann würde ich schlussfolgern, dass man den
> Stack der aufzurufenden Funktion zuvor "konstruieren" könnte, oder? Obgleich
> es sinnvoll ist, oder nicht.

Klar "konstruieren" kannst Du alles. Aber ohne Kenntnis der Daten kannst
Du da IMHO nichts, außer einen Speicherblock zu kopieren.
va_list ist an sich ja nichts anderes als ein Zeiger auf ein Stack Segment.
Das Problem ist immer nur wie die Daten, die dort stehen interpretiert
werden müssen. Und an die .NET Daten wirst Du so kaum heran kommen.

Warum machst Du es so kompliziert? Bau doch einen C++/Wrapper der die
eine .NET konforme Funktion bietet mit einem Objekt Array.

Matthias Friedrich

unread,
Dec 16, 2008, 7:26:06 AM12/16/08
to
Hallo Martin,

>
> Klar "konstruieren" kannst Du alles. Aber ohne Kenntnis der Daten kannst
> Du da IMHO nichts, außer einen Speicherblock zu kopieren.
> va_list ist an sich ja nichts anderes als ein Zeiger auf ein Stack Segment.
> Das Problem ist immer nur wie die Daten, die dort stehen interpretiert
> werden müssen. Und an die .NET Daten wirst Du so kaum heran kommen.
>
> Warum machst Du es so kompliziert? Bau doch einen C++/Wrapper der die
> eine .NET konforme Funktion bietet mit einem Objekt Array.
>

Habe ich auch so gemacht; hat mich nur interessiert, ob es prinzipiell (und
praktikabl) möglich gewesen wäre...

Danke und Gruss,
Matthias

0 new messages