![]() |
C Funktion, um zwei Strings zu verbinden in DLL
Zur Übung versuche ich gerade eine DLL in C zu schreiben, die mir zwei Strings verbindet und diese dann aus einem Delphi-Programm zu nutzen. Ich mache das erstmal mit dem VC2005, weil ich im Moment mit dem GCC und Eclipse nicht weiterkomme.
Meine C-Funktion in der DLL sieht so aus:
Code:
Der Delphi Code dazu:
extern "C" EXPORT int addstr(char *str1, char *str2, char *buffer)
{ strcat(str1, str2); strcpy(buffer, str1); return strlen(buffer); }
Delphi-Quellcode:
Aber ich bekomme in der DLL eine AccessViolation.
type
TAdd = function(a, b: Integer): Integer; stdcall; TAddStr = function(str1, str2: PChar; var Buffer: PChar): Integer; stdcall; procedure TForm1.Button1Click(Sender: TObject); var hLib: THandle; s: String; Add: TAdd; AddStr: TAddStr; res: Integer; str1, str2: String; Buffer: PChar; begin s := IncludeTrailingBackSlash(ExtractFilePath(ParamStr(0)))+ 'FirstDLL.dll'; hLib := LoadLibrary(PChar(s)); if hLib <> 0 then begin @Add := GetProcAddress(hLib, 'add'); if Assigned(Add) then begin res := Add(40, 2); ShowMessage(IntToStr(res)); end else ShowMessage(SysErrorMessage(GetLastError)); @AddStr := GetProcAddress(hLib, 'addstr'); if Assigned(AddStr) then begin str1 := 'Hello '; str2 := 'World'; GetMem(Buffer, length(str1) + length(str2)); try res := AddStr(PChar(str1), PChar(str2), Buffer); ShowMessage(string(Buffer)); finally FreeMem(Buffer); end; end else ShowMessage(SysErrorMessage(GetLastError)); FreeLibrary(hLib); end else ShowMessage(SysErrorMessage(GetLastError)); end; |
Re: C Funktion, um zwei Strings zu verbinden in DLL
Zitat:
Fehlt da nicht noch ein __stdcall, oder ist der Compiler so konfiguriert, dass es die Standardaufrufkonvention ist? ps: das 'var' vor Buffer ist zuviel. |
Re: C Funktion, um zwei Strings zu verbinden in DLL
Hi,
hast du es mal mit _fstrcat versucht? Könnte in deinem Fall sonst ein mögliches Problem werden. Bin nicht C-Crack genug um das hier mit Sicherheit sagen zu können, aber es gab ja Zeiten, in denen man ohne far-Pointer nur im Bereich von 64? KByte die Adressen haben durfte, bei einem Aufruf einer Dll kann das natürlich weniger garantiert werden. Gruß Der Unwissende |
Re: C Funktion, um zwei Strings zu verbinden in DLL
Wo kommt das __stdcall hin? Wenn ich es so mache:
Code:
Dann habe ich wieder das name mangling. Eine DEF Datei verwende ich nicht, deswegen das extern "C".
extern "C" EXPORT int __stdcall addstr(char *str1, char *str2, char *buffer)
Hm, bei API Funktionen macht man das aber doch auch so mit dem var in Delphi oder? |
Re: C Funktion, um zwei Strings zu verbinden in DLL
Zitat:
Nimm eine DEF. Zitat:
|
Re: C Funktion, um zwei Strings zu verbinden in DLL
Wie geht das mit der DEF Datei? Wo muss die hin in dem VC2005 Projektpfad? Und was muss in ihr drinen stehen? Und muss ich dem VC25005 noch irgendwie sagen, dass er die DEF-Datei verwenden soll?
Zitat:
|
Re: C Funktion, um zwei Strings zu verbinden in DLL
Zitat:
Zitat:
Code:
extern "C" EXPORT int addstr(char *str1, char *str2, char *buffer)
{ strcpy(buffer, str1); strcat(buffer, str2); return strlen(buffer); } |
Re: C Funktion, um zwei Strings zu verbinden in DLL
Yippieyeaho. Es geht. :firejump:
Also als erstes __stdcall in den Projektoptionen eingestellt. Dann eine DEFF-Datei erstellt:
Code:
Diese dem Linker bekannt gemacht: /DEF:FirstDLL.DEF und kompiliert. Rausgekommen ist eine DLL mit nicht dekorierten Funktionsnamen. Aufrugf von Delphi, wie gehabt ohne das var in der Funktionsdeklaration. Puh, jetzt kan ich auch Feierabend machen. ;)
LIBRARY FirstDLL.dll
EXPORTS add addstr Drei Dinge noch: Wie machen das API-Funktionen, dass man da in Delphi das Schlüsselwort var benutzen muss. Wie sicher ist die C-Funktion bezüglich BufferOverflows? Und zu guter letzt, wie muss ich es machen, damit meine C-Funktion die erforderliche Größe des Buffers zurückgibt, falls dieser zu klein ist beim Aufruf? |
Re: C Funktion, um zwei Strings zu verbinden in DLL
Zitat:
Delphi-Quellcode:
C:
function Foo(var c: Cardinal): Cardinal;
Code:
Sprich: Delphi macht var-Parameter implizit zu Pointern. Deswegen kann man vielen API-Funktionen, die irgendwas mit Records zu tun haben, diese direkt übergeben, ohne wie in C erst einen Pointer draus machen zu müssen.
DWORD Foo(PDWORD c);
|
Re: C Funktion, um zwei Strings zu verbinden in DLL
Aha. Bleiben noch Fragen zwei und drei. ;)
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:51 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz