C: Extrapolation von Typ aus void pointer

8

Sagen Sie, eine Funktion nimmt einen void-Zeiger als ein Argument, so: int func(void *p);
Wie können wir den Typ von dem, auf den p zeigt, bestimmen oder erraten?

    
Yktula 09.04.2010, 02:56
quelle

4 Antworten

20

Im Allgemeinen können Sie nicht. In einigen Fällen, wenn es eine Garantie gibt, auf was p verweist, können Sie in der Lage sein, den Inhalt an und nach dieser Adresse zu sehen, um herauszufinden. Im Allgemeinen sollte Ihre Funktion wissen, was übertragen wird, es sei denn, sie wird einfach weitergegeben.

Daten- und Funktionsargumente in C sind nur eine Ansammlung von Bits, die zusammengelegt werden. Wenn Sie nicht einige dieser Bits verwenden, um Ihnen zu sagen, was die Bits sind, gibt es keine konsistente Möglichkeit, sie zu identifizieren.

    
WhirlWind 09.04.2010, 02:58
quelle
5

Kurze Antwort - Sie können nicht.

In C gibt es keine Informationen zur Laufzeit, es sei denn, Sie stellen zur Verfügung, aber sehen Sie sich die % co_de an % Familie und sehen Sie, wie einfach es ist, sich selbst in den Fuß mit nicht übereinstimmenden Format-Spezifikation und tatsächlichen Argumenttyp schießen.

Typ System ist dein Freund. Benutze es.

    
Nikolai Fetissov 09.04.2010 03:24
quelle
5

Sicher kannst du, und es ist auch einfach. Es ist C, mach was du willst, wie du es willst.

Machen Sie ein Typsystem. Setze alles, was du passierst, in eine Struktur, mach das erste oder zwei Bytes zu einer magischen Zahl, um zu bestimmen, was die Struktur außerhalb der magischen Zahl enthält.

Nehmen Sie einige Funktionen vor, um die "typisierten Variablen" zu erstellen, abzurufen oder zu löschen.

Nehmen Sie einige andere Funktionen vor, um neue Typen zur Laufzeit hinzuzufügen und zu registrieren.

Erstellen Sie einige Definitionen, um das Lesen und Typisieren der Strukturen zu erleichtern.

Bevor Sie es wissen, werden Sie ein nettes proprietäres Typsystem haben, das Sie für Ihre Projekte verwenden können, und es wird GENAU immer tun, was Sie wollen und brauchen, weil Sie es gemacht haben.

Du könntest verrückt werden und es zu einem vollständigen objektorientierten System entwickeln. Oder rette die Arbeit und nutze die Arbeit all der anderen Leute, die bereits verrückt geworden sind - Ссылка

    
Antebellum 09.04.2010 03:43
quelle
1

Ich war mit einem ähnlichen Problem konfrontiert und musste selbst einen Befehlssatz für ein Programmiersprachenprojekt schreiben. Ich stieß auf dieses Problem, weil ich ein Array von Zeigern auf Funktionen hatte, so dass Funktionen aufgelistet und in einer for-Schleife ausgeführt werden konnten (für Dinge wie Online-Hilfe und Syntax usw.). Zum Beispiel:

%Vor%

Nun können Sie einfach dasselbe mit char * anstelle von struct List_Str * -Typen machen und dann alle Daten mit snprintf und atoi und atof und anderen Konvertierungsfunktionen in ein String-Format konvertieren. Wenn Sie ein:

%Vor%

Dies zeigt Ihnen viele Funktionen in ctype.h, die Ihnen Anregungen geben könnten, wie Sie bestimmen können, welcher Datentyp in den Strings enthalten ist.

Das Zusammenfalten aller Typen in ein "Stringy" -Format erlaubt eine enorme Flexibilität und Regelmäßigkeit, aber das automatische Konvertieren der Daten von den Strings in Integer, Floats usw. ist mühsam, aber sobald die Routinen lizensiert sind, ist es fruchtbar.

Wenn Sie beabsichtigen, binäre Daten zu speichern, können Sie keine Zeichenketten verwenden, da 0 Zeichen innerhalb der binären Daten sein können und dies strlen Funktionen verwirrt. Darüber hinaus haben Sie keine Ahnung von der Länge von dem, was malloziert wurde, sobald es den Gültigkeitsbereich verlässt, also die Länge der dereferenzierten Daten zu speichern, bevor die Daten in den ersten paar Bytes von char * empfohlen werden.

Eine letzte Sache, ich würde nicht empfehlen, Daten in void * zu speichern, es ist zu vage. Ich empfehle char * zu verwenden, da es etwas genauer ist, alles enthalten kann, was nichtig ist * und der Compiler wird Sie vorher informieren, wenn etwas faul aussieht.

    
Owl 22.05.2013 22:41
quelle

Tags und Links