Einbinden einer (C-)DLL
-
Hallo,
ich habe eine Library welche mir Funktionen zur Verfügung stellt, die ich gerne in einem C#-Projekt nutzen würde. Das ich externe Funktionen, aus einer DLL, über das Attribut DllImport einbinde, weiß ich.
Das Problem liegt eher darin, dass mir DLL-Funktionen Datensätze liefern. Beispielhaft hätte ich folgende Funktionen:
void* LoadRecord(void* buffer); bool StoreRecord(void const* data);
Wie würde ich diese Funktionen in C# deklarieren? Zudem mache ich mir Sorgen, um das Alignment. Gibt es in C# Mäglichkeiten einen "packed" Typ zu deklarieren?
Für Informationen wäre ich überaus dankbar.EDIT:
Bezüglich des Alignments, scheint folgende Deklaration das Gesuchte zu sein:[StructLayout(LayoutKind.Sequential, Pack=1)]
-
[DllImport( @"deine.dll", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, EntryPoint = @"LoadRecord") IntPtr LoadRecord(IntPtr buffer); [DllImport( @"deine.dll", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, EntryPoint = @"LoadRecord") [return: MarshalAs(UnmanagedType.I1)] bool StoreRecord(IntPtr data);
Pack
ist der richtige Named-Parameter für einen "packed" Typ.
Die Frage ist aber, was du an die Funktionen übergeben willst.IntPtr
ist das Gegenstück zuvoid*
und daran kann man keine Strukturen/Klassen einfach übergeben. Allenfalls musst du über die KlasseMarshal
gehen oder die Signatur entsprechend verändern. Mehr Informationen während für genauere Angaben definitiv nötig.Grüssli
PS: Ich fühle mich genötigt, endlich an diesem "FAQ-Artikel" über P/Invoke weiterzuarbeiten. Nächste Woche Zeit dafür reservieren ...
-
Die Signatur verändern kann ich nicht. Der Record-Typ der geladen wird, ist immer ein anderer. Kann ich ggf. nicht einfach zur entsprechenden struct casten?
Das hoer geht nicht oder?
struct myStruct {} LoadRecord(ref myStruct);
-
FrEEzE2046 schrieb:
Die Signatur verändern kann ich nicht.
Ich meinte eigentlich die C# Import Signatur
FrEEzE2046 schrieb:
Der Record-Typ der geladen wird, ist immer ein anderer. Kann ich ggf. nicht einfach zur entsprechenden struct casten?
Es ist vieles möglich, man müsste nur mal erfahren, was für Strukturen du übergeben tust oder zurückerhälst.
FrEEzE2046 schrieb:
Das hoer geht nicht oder?
struct myStruct {} LoadRecord(ref myStruct);
Doch, sowas kann schon gehen, ich weiss aber nicht, ob es das Verhalten ist, welches du möchtest, da ich, wie gesagt, keine Ahnung habe, was du den Funktionen übergeben willst oder zurückerhälst.
Grüssli
-
Ich meinte auch die Signatur auf Seiten von C#. Ich möchte den Funktionen simple structs übergeben, die integrale, alphanumerische und Gleitkommatypen enthalten.
Diese structs möchte ich speichern und laden können. LoadRecord() füllt "buffer" mit sizeof(struct) byte.Alles recht simpel also. Es ist nur wichtig, dass sizeof(struct) auf der Seite von C genau das selbe ist, wie dann in C#. Daher kam die Alignment Frage auf.
-
FrEEzE2046 schrieb:
Ich meinte auch die Signatur auf Seiten von C#. Ich möchte den Funktionen simple structs übergeben, die integrale, alphanumerische und Gleitkommatypen enthalten.
Diese structs möchte ich speichern und laden können. LoadRecord() füllt "buffer" mit sizeof(struct) byte.Alles recht simpel also. Es ist nur wichtig, dass sizeof(struct) auf der Seite von C genau das selbe ist, wie dann in C#. Daher kam die Alignment Frage auf.
Und wie kannst du
sizeof(struct)
machen, wenn du nur einen Zeiger aufvoid
übergibst?
Und wieso kannst du die C# Signatur nicht verändern, wenn du sie ja selber erstellst?
Und wieso erstellst du nicht C Funktionen für jeden Typ und dazu passende Signaturen in C#?Also ich bin jetzt völlig verwirrt. Falls du also noch irgendwelche Hilfe zum Problem benötigst, dann musst du mir das mal ein wenig ausführlicher erklären und nicht immer so ein paar Bruchstücke auf den Tisch werfen.
Grüssli