AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein C Funktion, um zwei Strings zu verbinden in DLL
Thema durchsuchen
Ansicht
Themen-Optionen

C Funktion, um zwei Strings zu verbinden in DLL

Ein Thema von Luckie · begonnen am 16. Aug 2006 · letzter Beitrag vom 17. Aug 2006
Antwort Antwort
Seite 1 von 3  1 23      
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#1

C Funktion, um zwei Strings zu verbinden in DLL

  Alt 16. Aug 2006, 15:09
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:
extern "C" EXPORT int addstr(char *str1, char *str2, char *buffer)
{   
    strcat(str1, str2);
   strcpy(buffer, str1);   
   return strlen(buffer);
}
Der Delphi Code dazu:
Delphi-Quellcode:
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;
Aber ich bekomme in der DLL eine AccessViolation.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
NicoDE
(Gast)

n/a Beiträge
 
#2

Re: C Funktion, um zwei Strings zu verbinden in DLL

  Alt 16. Aug 2006, 15:15
Zitat von Luckie:
extern "C" EXPORT
Kannst du dir sparen wenn du eine DEF-Datei verwendest (EXPORTS).
Fehlt da nicht noch ein __stdcall, oder ist der Compiler so konfiguriert, dass es die Standardaufrufkonvention ist?

ps: das 'var' vor Buffer ist zuviel.
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#3

Re: C Funktion, um zwei Strings zu verbinden in DLL

  Alt 16. Aug 2006, 15:20
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
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#4

Re: C Funktion, um zwei Strings zu verbinden in DLL

  Alt 16. Aug 2006, 15:21
Wo kommt das __stdcall hin? Wenn ich es so mache:
Code:
extern "C" EXPORT int __stdcall addstr(char *str1, char *str2, char *buffer)
Dann habe ich wieder das name mangling. Eine DEF Datei verwende ich nicht, deswegen das extern "C".

Hm, bei API Funktionen macht man das aber doch auch so mit dem var in Delphi oder?
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
NicoDE
(Gast)

n/a Beiträge
 
#5

Re: C Funktion, um zwei Strings zu verbinden in DLL

  Alt 16. Aug 2006, 15:25
Zitat von Luckie:
Dann habe ich wieder das name mangling. Eine DEF Datei verwende ich nicht, deswegen das extern "C".
Name Mangling hast du so oder so (ob nun _foo oder _foo@x ist doch egal).
Nimm eine DEF.

Zitat von Luckie:
Hm, bei API Funktionen macht man das aber doch auch so mit dem var in Delphi oder?
*char ist ein PAnsiChar, keine Referefenz auf eine PAnsiChar-Variable.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#6

Re: C Funktion, um zwei Strings zu verbinden in DLL

  Alt 16. Aug 2006, 15:29
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:
*char ist ein PAnsiChar, keine Referefenz auf eine PAnsiChar-Variable.
Wie machen denn das API Funktionen?
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von Flocke
Flocke

Registriert seit: 9. Jun 2005
Ort: Unna
1.172 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#7

Re: C Funktion, um zwei Strings zu verbinden in DLL

  Alt 16. Aug 2006, 15:45
Zitat von Luckie:
Meine C-Funktion in der DLL sieht so aus:
Code:
extern "C" EXPORT int addstr(char *str1, char *str2, char *buffer)
{   
    strcat(str1, str2);
   strcpy(buffer, str1);   
   return strlen(buffer);
}
Zitat von Luckie:
Aber ich bekomme in der DLL eine AccessViolation.
Das liegt wohl daran, dass du dir in C "str1" überschreibst. Richtiger wäre:
Code:
extern "C" EXPORT int addstr(char *str1, char *str2, char *buffer)
{   
    strcpy(buffer, str1);   
    strcat(buffer, str2);
    return strlen(buffer);
}
Volker
Besucht meine Garage
Aktuell: RtfLabel 1.3d, PrintToFile 1.4
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#8

Re: C Funktion, um zwei Strings zu verbinden in DLL

  Alt 16. Aug 2006, 15:57
Yippieyeaho. Es geht.

Also als erstes __stdcall in den Projektoptionen eingestellt. Dann eine DEFF-Datei erstellt:
Code:
LIBRARY FirstDLL.dll

EXPORTS
   add
   addstr
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.

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?
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Dax
(Gast)

n/a Beiträge
 
#9

Re: C Funktion, um zwei Strings zu verbinden in DLL

  Alt 16. Aug 2006, 16:12
Zitat von Luckie:
Wie machen das API-Funktionen, dass man da in Delphi das Schlüsselwort var benutzen muss.
Delphi:function Foo(var c: Cardinal): Cardinal; C:
Code:
DWORD Foo(PDWORD c);
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.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#10

Re: C Funktion, um zwei Strings zu verbinden in DLL

  Alt 16. Aug 2006, 16:14
Aha. Bleiben noch Fragen zwei und drei.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:12 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz