Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Portal
  • |
  • Mitglieder
Beiträge von Spook
Thema: TAPI DLL in Projekt einbinden geht nicht
Am im Forum: Rund um die Programmierung

Hallo,

nachdem du den Verweis auf die COM dll hinzugefügt hast, musst du die Eigenschaften dieses öffnen und dort das Einbetten deaktivieren.

spooky

Thema: kopieren bzw initialisieren von Bitmaps ändert Bittiefe
Am im Forum: Grafik und Sound

Hallo,

ich habe mal die Methode Clone wie von MrSparkle genannt versucht, und diese funktionierte bei mir ohne Probleme (8bppindexed).


public static Bitmap Clone(Bitmap bitmap)
{
    if (bitmap == null)
        throw new ArgumentNullException("bitmap");
    Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
    return bitmap.Clone(rect, bitmap.PixelFormat);
}

Sollte diese trotzdem nicht funktionieren, kannst du die Daten auch manuell klonen:


public static Bitmap Clone2(Bitmap bitmap)
{
    if (bitmap == null)
        throw new ArgumentNullException("bitmap");

    Bitmap clone;
    Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
    BitmapData bmpData = bitmap.LockBits(rect, ImageLockMode.ReadOnly, bitmap.PixelFormat);
    try
    {
        clone = new Bitmap(bmpData.Width, bmpData.Height, bmpData.Stride, bmpData.PixelFormat, bmpData.Scan0);
    }
    finally
    {
        bitmap.UnlockBits(bmpData);
    }
    clone.Palette = bitmap.Palette;
    return clone;
}

Ich hoffe das hilft dir weiter zum Thema klonen.

Warum das manuelle Kopieren von dir nicht funktioniert liegt am Layout der Farbstruct. Diese ist nicht ARGB sondern BGRA (siehe RGBQUAD):

typedef struct tagRGBQUAD { 
  BYTE rgbBlue;
  BYTE rgbGreen;
  BYTE rgbRed;
  BYTE rgbReserved;
} RGBQUAD;

Grüße

spooky

Thema: Lockfreie threadsichere Queue
Am im Forum: .NET-Komponenten und C#-Snippets

Hallo,

man sollte Dequeue noch so erweitern, dass vor dem Verlassen der Methode das zurückgegebene Element aus der Datenstruktur entfernt wird:


    ...
    item = current.next.item;
    current.next.item = default(T);
    return true;
}

Bei Dequeue wird die Verkettete Liste um eine Element verschoben (effektiv: last wird zu last.next). Dabei wird diese Node zum neuen "Anker" der Liste und wird NICHT vom GC abgeräumt - auch nicht das darin enthaltene Element.

Grüße

spooky

Thema: Kombination von optionalen Parametern und params ...[] unmöglich?
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Hallo,

der optionale Parameter ist nur dann optional, wenn du weder ihn, noch Parameter rechts von ihm angibst. Da du den Paramter "Zusaetzliches" angibst, musst du auch "JaNein" angeben (in vb kann man glaube ich, auch optionale Parameter in der Mitte weglassen).
Was funktionieren würde, wäre gar keinen Parameter anzugeben.

spooky

Thema: Compiler bevorzugt generische Methodenvariante --> Compilerfehler
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Hallo,

etwas zu deiner Klasse selbst ...

public static class EqualsExtensions
{
	public static bool EqualsOneOf(this object first, params object[] others)
	{
		return others.Any(o => Object.Equals(first, o));
	}

	public static bool EqualsOneOf<T>(this IEquatable<T> first, params T[] others)
	{
		if (Object.ReferenceEquals(first, null))
			return others.Any(o => Object.ReferenceEquals(o, null));

		return others.Any(o => first.Equals(o));
	}
}

Wäre diese Implementierung nicht "korrekter"? Die Methode soll schauen ob "first" zu einem der folgenden Objekte equivalent ist. Dies bedeut aber streng genommen nicht, dass diese auch IEquatable<T> implementieren, sondern nur vom Typen T sein müssen.

Spooky

Thema: C++ DLL für C# erstellen (DllImport)
Am im Forum: Rund um die Programmierung

Hallo,

ich hab das Projekt mal umgebaut. Die .dll muss nurnoch ins Ausgabe-Verzeichnis des .NET Projektes kopiert werden.

Spooky

PS: StringBuilder braucht man wenn man einen Buffer _übergibt_ in den geschrieben werden soll. Diese Funktionen haben dann meistens noch einen Parameter, der die Bufferlänge angibt zb:
void FillMe(char * buffer, int length, ...);
->
void FillMe(StringBuilder b, int length, ...);

Wenn es um fixe Strings geht braucht man keinen StringBuilder anlegen.

edit:
Der .NET Typ DateTime und der C++ Typ time_t sind wohl doch nicht kompatibel, daher musst du wohl einen kompatiblen Typen suchen oder Hilfsmethoden implementieren.

Thema: C++ DLL für C# erstellen (DllImport)
Am im Forum: Rund um die Programmierung

DateTime ist intern ein .NET long. Der C++ Typ time_t (time.h), der intern ebenfalls ein 64bit Integer ist könnte dafür ggf verwerdendet werden. Time Beispiel

Wie zommi schon gesagt hat, ist char * der Typ den du verwenden solltest. Ggf kannst du auch wchar_t * (Unicode) nehmen:


#include <time.h>
LPCWSTR __stdcall Generate(LPCWSTR s1, LPCWSTR s2, LPCWSTR s3, int number, time_t time);

Thema: C++ DLL für C# erstellen (DllImport)
Am im Forum: Rund um die Programmierung

Hallo JunkyXL,

am besten gehst du so vor:

Neues Projekt anlegen (Visual C++ -> Win32-Projekt) mit Anwendungstyp "Dll". Andere Optionen lassen, wie sie sind.

In der erzeugten .cpp Datei kannst du nun zB eine Funktion so deklarieren:


// Gehört eigentlich in die .h Datei
extern "C"
{
	BOOL __declspec(dllexport) __stdcall CheckKey(const unsigned char *key);
}

BOOL __stdcall InternalHelper(const unsigned char *key);
// Ende .h Datei

// Kann von aussen aufgerufen
BOOL __stdcall CheckKey(const unsigned char *key) {
	return InternalHelper(key);
}

// Nur intern verwendbar
BOOL __stdcall InternalHelper(const unsigned char *key) {
	return FALSE;
}

Dabei ist zu beachten, dass Funktionen die mit __declspec(dllexport) deklariert sind, nach aussen exportiert werden (d.h. Hilfsmethoden ohne dieses Tag können auch von aussen nicht aufgerufen werden).

Spooky

Thema: Struct von C++ nach C#
Am im Forum: Rund um die Programmierung

IntPtr strData = new IntPtr(plstr.ToInt32() + 4);

sollte noch in

IntPtr strData = new IntPtr(unchecked(plstr.ToInt64() + 4));

geändert werden um auch unter 64bit zu funktionieren. Ggf könnte man die Offset Operation noch in eine sperate Methode mit Over-/Underflow Check auslagern.

Spooky

Thema: Gibts es vorgefertigte Reference-Wrapperklassen für Wertetypen ?
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Ein etwas aufgemotzerer Ansatz ...

public class Reference<T> where T : struct
{
	[DebuggerBrowsable(DebuggerBrowsableState.Never)]
	protected T value;

	public Reference()
	{

	}

	public Reference(T value)
	{
		this.value = value;
	}

	public static implicit operator T(Reference<T> value)
	{
		return value.value;
	}

	public static implicit operator Reference<T>(T value)
	{
		return new Reference<T>(value);
	}

	public T Value
	{
		get { return value; }
		set { this.value = value; }
	}

	public override string ToString()
	{
		return value.ToString();
	}

	public override int GetHashCode()
	{
		return value.GetHashCode();
	}

	public override bool Equals(object obj)
	{
		return (obj is Reference<T>) && value.Equals(((Reference<T>)obj).value);
	}
}

Thema: Gibts es vorgefertigte Reference-Wrapperklassen für Wertetypen ?
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Hallo,

deine Wrapper-Klasse ist genau richtig um aus einem Werttypen einen Referenztypen zu machen.
Nullable<T> macht aus einem Werttypen einen null-baren Typen, aber keinen Referenztyp.

Spooky

Thema: Struct von C++ nach C#
Am im Forum: Rund um die Programmierung

Hallo,

auch den Datentyp long solltest du genauer anschauen, da dieser normalerweile 4 byte groß ist, welches ein int in .NET wäre.

Spooky

Thema: Wo finde ich das .NET-Equivalent zum Java-Bitset?
Am im Forum: Rund um die Programmierung

Hallo,

System.Collections.BitArray sollte dem sehr nahe kommen.

Spooky

Thema: mehrere Bilder in einem BLOB speichern
Am im Forum: Datentechnologien

Hallo scoda,

ich würde den Blob so aufbauen:

[Länge der Bilddaten][Bilddaten][Länge der Bilddaten][Bilddaten][Länge der Bilddaten][Bilddaten]

So kannst du einfach Bilder anfügen oder durch die Datei zum x-ten Bild springen.

Spooky

Thema: PerformanceCounter: Processor / % Processor Time / _Total = immer 0.0
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Hallo lord_fritte,

siehe Dokumentation:

Zitat
Wenn der berechnete Wert eines Zählers von zwei Zählerlesevorgängen abhängt, gibt der erste Lesevorgang 0,0 zurück. Das Zurücksetzen der Leistungsindikatoreigenschaften, um einen anderen Indikator anzugeben, entspricht dem Erstellen eines neuen Leistungsindikators, und beim ersten Lesevorgang mit den neuen Eigenschaften wird 0,0 zurückgegeben. Die empfohlene Verzögerungszeit zwischen Aufrufen der NextValue-Methode beträgt eine Sekunde, um es dem Indikator zu ermöglichen, den nächsten inkrementellen Lesevorgang auszuführen.

PerformanceCounter pCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
pCounter.NextValue();
while (true)
{
    Thread.Sleep(1000);
    Console.WriteLine(pCounter.NextValue());
}

Spooky

Thema: [gelöst] Überladen von "==": Null abfangen?
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Wie dN!3L schon geschrieben hat ist ReferenceEquals (oder der cast nach Object) eine Lösung, hier in einem einfachen Beispiel:

		class Point
		{
			public double X { get; set; }
			public double Y { get; set; }

			public static bool operator ==(Point a, Point b)
			{
				if (ReferenceEquals(a, b))
				{
					return true;
				}
				if (ReferenceEquals(a, null) || ReferenceEquals(b, null))
				{
					return false;
				}
				return ((a.X == b.X) && (a.Y == b.Y));
			}

			public static bool operator !=(Point a, Point b)
			{
				return (!(a == b));
			}
		}

Spooky

Thema: Ansicht-Designer soll Code nicht ausführen
Am im Forum: Entwicklungs- und Laufzeitumgebung (Infrastruktur)

Hallo Tom,

vielleicht hilft dir dies weiter.

Component.DesignMode-Eigenschaft

Spooky

Thema: 32bit Bitmap in 16bit Bitmap umwandeln
Am im Forum: Grafik und Sound

Hallo S.R.,

Zitat von S.R.
Leider ist das Ergebnis weiterhin, dass result.bmp genauso groß ist und die gleiche Auflösung hat wie test-1.bmp. Hat jemand einen weiteren Tipp auf LAger, was hier schief läuft?

Bei mir liefert die Clone Methode schon ein 32-bit Bild zurück. Von daher ist es nur logisch, dass die Datei dann auch 32-bit ist.

Du könntest diese Methode verwenden:

public static Bitmap ConvertBitmap(Bitmap bitmap, PixelFormat format)
{
    if (bitmap == null)
    {
        throw new ArgumentNullException("bitmap");
    }

    Bitmap result = null;
    try
    {
        Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
        result = new Bitmap(bitmap.Width, bitmap.Height, format);

        BitmapData dstData = result.LockBits(rect, ImageLockMode.WriteOnly, format);
        try
        {
            BitmapData srcData = new BitmapData();
            srcData.Scan0 = dstData.Scan0;
            srcData.Stride = dstData.Stride;

            bitmap.LockBits(rect, ImageLockMode.ReadOnly | ImageLockMode.UserInputBuffer, format, srcData);
            bitmap.UnlockBits(srcData);
        }
        finally
        {
            result.UnlockBits(dstData);
        }
    }
    catch
    {
        if (result != null)
        {
            result.Dispose();
        }
        throw;
    }
    return result;
}

Dabei solltest du jedoch beachten, dass GDI+ bzw .NET kein Format16bppArgb1555 unterstützen. D.h. du musst dich mit Format16bppRgb555 oder Format16bppRgb565 begnügen.

Spooky

Edit: Methode geändert, sodass keine 3. temporäre Bitmap erzeugt wird. So schreibt die eine Bitmap die Pixeldaten direkt in die andere.

Thema: DllImport - LPByte mit Marshal.AlocHGlobal ... CMD-Fenster schließt erst nach etwa 10s (siehe unten)
Am im Forum: Rund um die Programmierung

Hallo ibuddy,

von den Namen der Datentypen her würde ich die Klasse so definieren:

        [StructLayout(LayoutKind.Sequential, Size = 20)] // event. in der dllimport dann als "[in,out] S_RESOLUTION_PARAMS ResParam" aufrufen
        public class S_RESOLUTION_PARAMS
        {
            public short wOffsetX;       // i16 X offset of ROI (relative to visible area).
            public short wOffsetY;       // i16 Y offset of ROI (relative to visible area).
            public ushort wSizeX;         // u16 X size (width, columns) of ROI.
            public ushort wSizeY;         // u16 Y size (height, lines) of ROI.
            public uint dwSkip;         // u32 X- and Y- Skip Settings (see XY_SKIP_NONE).
            public uint dwBin;          // u32 X- and Y- Bin Settings (see XY_BIN_NONE).
            public byte bKeepExposure;  // u08 keep constant exposure (true=yes, false=no)
        };

Durch die Angabe der absoluten Größe kannst du das Array weglassen (welches eh nur fürs Alignment ist).

Zu der C++ Anweisung:
"pResCap = (S_RESOLUTION_CAPS*) new (BYTE[dwCapSize]);"

In C++ kannst du Speicher mit dem new Operator allokieren. In dem Fall wird ein byte-array der Größe "dwCapSize" allokiert. Durch den Cast (S_RESOLUTION_CAPS*) kann nun der Speicher so verwendet werden, als sei es ein Array von "S_RESOLUTION_CAPS".
new

Spooky

Thema: Unmanaged Int-Pointer in managed float-Array umwandeln
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Hallo,

         public static float[][] GetMatrix(IntPtr ptr)
        {
            float[][] result = new float[4][];
            for (int i = 0; i < 4; i++)
            {
                IntPtr arrayPtr = Marshal.ReadIntPtr(ptr, i);
                float[] floats = new float[4];
                Marshal.Copy(arrayPtr, floats, 0, 4);
                result[i] = floats;
            }
            return result;
        }

So könnte es funktioneren, wenn es ein einfach verschachteltes Array ist.

Spooky

Thema: Serialisierung fixed byte[] in Struct
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Hallo,

so sollte es gehen:


[StructLayout(LayoutKind.Sequential, Size = 512), Serializable]
public struct DMXStep : ISerializable
{
    private byte m_firstByte;

    private unsafe DMXStep(SerializationInfo info, StreamingContext context)
    {
        fixed (byte* p = &m_firstByte)
        {
            byte[] data = (byte[])info.GetValue("DATA", typeof(byte[]));
            for (int i = 0; i < 512; i++)
                p[i] = data[i];
        }
    }
    
    public unsafe byte this[int index]
    {
        get
        {
            fixed (byte* p = &m_firstByte)
            {
                return p[index];
            }
        }
        set
        {
            fixed (byte* p = &m_firstByte)
            {
                p[index] = value;
            }
        }
    }

    #region ISerializable Member

    unsafe void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
    {
        fixed (byte* p = &m_firstByte)
        {
            byte[] data = new byte[512];
            for (int i = 0; i < 512; i++)
                data[i] = p[i];
            info.AddValue("DATA", data);
        }
    }

    #endregion
}

Spooky

Thema: Serialisierung fixed byte[] in Struct
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Hallo,

das unsafe byte-Array ist ein vom Compiler generierter Typ, der nicht als serialisierbar gekennzeichnet ist:

[StructLayout(LayoutKind.Sequential, Size=x), CompilerGenerated, UnsafeValueType]
public struct <bytes>e__FixedBuffer0
{
    public byte FixedElementField;
}

Spooky

Thema: FileInfo.ToString() liefert nach file.MoveTo() FullName statt Name
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Hallo,

ToString() gibt den String zurück, der beim erstellen/verschieben übergeben wurde.

Spooky

Thema: Prozess ID des Aufrufenden Prozess' ermitteln.
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Hallo inva,

mit WMI kannst du die ParentProcessId auslesen:

static bool TryGetParentProcessId(out int id)
{
	try
	{
		int ownId = Process.GetCurrentProcess().Id;
		ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_Process WHERE ProcessId=" + ownId);
		foreach (ManagementBaseObject row in searcher.Get())
		{
			id = (int)(uint)row["ParentProcessId"];
			return true;
		}
	}
	catch
	{

	}
	id = 0;
	return false;
}

static void Main(string[] args)
{
	int id;
	if (TryGetParentProcessId(out id))
		Console.WriteLine(Process.GetProcessById(id).ProcessName+ " called me.");
	else
		Console.WriteLine("Unable to identify caller.");
}

Spooky

Thema: Point-array von c# nach c++
Am im Forum: Rund um die Programmierung

Hallo,

eine Möglichkeit wäre einen Custom Marshaler zu implementieren. Dann könnten die PInvokes zB so aussehen:

[DllImport("some.dll")]
private static extern bool SomeFunction(
    [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PolygonMarshaler))] Polygon polygon);

[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PolygonMarshaler))]
[DllImport("some.dll")]
private static extern Polygon SomeOtherFunction();

Die Implementierung könnte dann so aussehen:

public sealed class Polygon
{
    public Header header;
    public Parms parms;
    public PointD[] points;
}

[StructLayout(LayoutKind.Sequential, Size = 1)]
public struct Header { }

[StructLayout(LayoutKind.Sequential, Size = 1)]
public struct Parms { }

public struct PointD
{
    public double x;
    public double y;
}

internal sealed class PolygonMarshaler : ICustomMarshaler
{
    private unsafe struct Poly
    {
        public Header header;
        public Parms parms;
        public ushort pointCount;
        public fixed PointD points[1];
    }

    private static ICustomMarshaler m = new PolygonMarshaler();

    private static ICustomMarshaler GetInstance(string s)
    {
        return m;
    }

    #region ICustomMarshaler Member

    public void CleanUpManagedData(object ManagedObj)
    {

    }

    public void CleanUpNativeData(IntPtr pNativeData)
    {
        Marshal.FreeHGlobal(pNativeData);
    }

    public unsafe int GetNativeDataSize()
    {
        return sizeof(Poly);
    }

    public unsafe IntPtr MarshalManagedToNative(object ManagedObj)
    {
        if (!(ManagedObj is Polygon))
            return IntPtr.Zero;

        Polygon polygon = (Polygon)ManagedObj;

        int size = sizeof(Poly);
        if ((polygon.points != null) && (polygon.points.Length > 1))
            size += ((polygon.points.Length - 1) * sizeof(PointD));
        Poly* ptr = (Poly*)Marshal.AllocHGlobal(size);

        ptr->header = polygon.header;
        ptr->parms = polygon.parms;
        ptr->pointCount = (ushort)(polygon.points == null ? 0 : polygon.points.Length);
        for (int i = 0; i < ptr->pointCount; i++)
            ptr->points[i] = polygon.points[i];

        return (IntPtr)ptr;
    }

    public unsafe object MarshalNativeToManaged(IntPtr pNativeData)
    {
        if (pNativeData == IntPtr.Zero)
            return null;

        Polygon result = new Polygon();
        Poly* ptr = (Poly*)pNativeData;

        result.header = ptr->header;
        result.parms = ptr->parms;
        result.points = new PointD[ptr->pointCount];

        for (int i = 0; i < ptr->pointCount; i++)
            result.points[i] = ptr->points[i];

        return result;
    }

    #endregion
}

Hier fehlen noch die konkreten Implementierungen von Header und Parms.

Ich hoffe du kannst damit einen Einstieg finden. Vielleicht lässt sich das auch eleganter nur unter der Verwendung der unsafe struct Poly lösen, kommt ganz drauf an, ob und wie du die eigentliche Klasse verwenden willst.

Spooky

Thema: verschiedene Elemente in einem Array zählen
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Hallo,

so kannst du die einzelnen Elemente zählen:

            string[] myArray = new string[10] { "0", "0", "0", "0", "0", "1", "1", "1", "1", "2" };
            Dictionary<string, int> dict = new Dictionary<string, int>();
            int c;
            foreach (string s in myArray)
            {
                if (!dict.TryGetValue(s, out c))
                    c = 0;
                dict[s] = (c + 1);
            }
            foreach (KeyValuePair<string, int> kvp in dict)
            {
                //
            }

Spooky

Thema: Point-array von c# nach c++
Am im Forum: Rund um die Programmierung

Hallo,

der Member points ist kein Zeiger auf ein PointArray sondern ein in die Struct eingebettetes Array von konstanter Größe 1.
Dadurch kann man wie bei einem Array auf die Punkte zugreifen. Es muss natürlich, wie Th69 schon geschrieben hatte, für jeden weiteren Punkt auch mehr Speicher allokiert werden:

tagApiPolygonObjectV1_NEW *poly =
   (tagApiPolygonObjectV1_NEW *)malloc(sizeof(tagApiPolygonObjectV1_NEW) + (sizeof(IN_POINT) * 3));
poly->pointCount = 4;
poly->points[0] = ...;
poly->points[1] = ...;
poly->points[2] = ...;
poly->points[3] = ...;

Spooky

Thema: Eure Kritik: Fraction struct
Am im Forum: Rund um die Programmierung

Hallo m0rius,

du könntest auch den Typ Decimal näher betrachten (statische Operatoren, Konstanten, sinnvolle Methoden).

Spooky

Thema: c++ code zu c#: unsigned char ** buffer
Am im Forum: Rund um die Programmierung

Hallo,


IntPtr ptr = Marshal.AllocHGlobal(16635);
IntPtr ptrptr = Marshal.AllocHGlobal(ptr);

Dieser Code erzeugt keinen Zeiger auf den ersten Buffer, sondern zwei von einander komplett unabhängige Buffer.

Die wohl sinnigste Deklaration wäre (wie schon gesagt) ref IntPtr.

Allerdings kommt dann das nächste Problem ...
In deinem Code wird der allokierte Speicher nicht wieder freigegeben, was man natürlich noch einbauen könnte. Jedoch wird einem der Zeiger auf den allokierten Speicher ...
*buffer+=netLen;

unter der Nase weg verändert ... (guter Stil?). Zwar wird der veränderte Wert in len wieder zurückgegeben, aber nun muss man entweder wieder rückwerts rechnen, oder sich den Zeiger doppelt vorhalten um auf die Daten zuzugreifen und den Speicher wieder freizugeben.

Wenn ich eine Funktion mit einem Buffer habe, gehe ich davon aus, dass der Buffer gefüllt wird mit Daten. Dabei kann ich ein ggf ein Offset angeben und die Länge des Buffers. Aber eine Funktion sollte dem Aufrufer nicht die Zeiger "verbiegen".

Thema: EXIF-Daten auslesen -> komische zeichen
Am im Forum: Grafik und Sound

http://www.exif.org/Exif2-2.PDF

Am besten nach den Konstanten suchen, und die Daten-Typen beachten (signed/unsigned). Mit Hilfe der BitConverter Klasse sollte das recht einfach gehen.

Spooky