Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   C-Funktions-Aufruf SetText(char* szLine); nach Delphi (https://www.delphipraxis.net/111218-c-funktions-aufruf-settext-char%2A-szline-%3B-nach-delphi.html)

TERWI 31. Mär 2008 17:55


C-Funktions-Aufruf SetText(char* szLine); nach Delphi
 
Moin zusammen !

Ich habe hier ein Display mit FB (IMON) von Soundgraph und dazu gibt's ne kleine API/DLL, mit der ich u.a. 2 Zeilen freien Text auf das Display zaubern kann. Alles in C - logo... Einbinden der DLL funzt soweit, aber irgendwie bekomme ich nix gescheites auf das Display.

Die Deklaration im C-Header-File lautet exakt:
Delphi-Quellcode:
IMONVFD_API bool iMONVFD_SetText(char* szFirstLine, char* szSecondLine);
Ich habe daraus gemacht:
Delphi-Quellcode:
function VFD_SetText(TXT1, TXT2 : PChar) : bool; external 'SG_VFD.dll' name 'iMONVFD_SetText';
Das frisst die DLL auch so ohne Gemaule und gibt TRUE als Ergebnis zurück. Aber im Display kommt nur Murks an.
Habe diverses versucht, aus 2 Edit's irgendwie den Text als PChar zu übergeben - aber nix.
Ich weiss, ich habe so was schon mal gemacht, aber wann und wo...
Kann mal jemand nem C-Allergiker auf die Sprünge helfen ? Dank im vorraus !

shmia 31. Mär 2008 18:07

Re: C-Funktions-Aufruf SetText(char* szLine); nach Delphi
 
Zitat:

Zitat von TERWI
Aber im Display kommt nur Murks an.

<Glasskugel>
Vielleicht ist das Display im Grafik Mode, während du es mit Textmode Funktionen ansprichst ? </Glasskugel>
Ansonsten: du solltest zuerst ein Demo Programm (zur Not den C Code compilieren und linken) nehmen und prüfen, ob das Display prinzipiell in Ordnung ist.
Dann kommts auch auf die Aufrufkonvention an (entweder stdcall oder cdecl):
Delphi-Quellcode:
const SG_VFD_DLL = 'SG_VFD.dll'; // gleich vorsorgen und den Namen der DLL als Konstante verwenden
function VFD_SetText(TXT1, TXT2 : PChar) : bool; stdcall; external SG_VFD_DLL name 'iMONVFD_SetText';

TERWI 31. Mär 2008 18:38

Re: C-Funktions-Aufruf SetText(char* szLine); nach Delphi
 
Vielleicht war das etwas unklar...

Es kommt ja schon was auf dem Display an, allerdings nur Hyroglyphen, so als wenn man irgendwo im Speicher was rausgreift, was kein Text ist.
Das mit dem DLL-Namen als CONST habe ich auch schon so im Text, nur einfach weggelassen - der übersichtlichkeit halber ?!
Die Aufrufkonvention STDCALL und andere habe ich auch schon probiert >>> Das gibt nur AccessViolations ohne Ende.

Die Funktion als solche scheint ja auch irgendwie zu funken: Dargestellter Text von IMON verschwindet und die Funktion als solche liefert TRUE zurück. Dazu muss ich in IMON erst einmal einstellen, das 'Dritte' das Display verwenden (muss man z.B. für Girder so machen). Mache ich das nicht, kommt false zurück.
Also scheint eine grundsätzlich in der Art Kommunikation zu klappen.

Meine Frage war nur:

Wie konvertiere ich die Strings aus den beiden Edit1.Text und Edit2.Text in PChar für die TXT1- und TXT2-Parameter der Funktion. Ich denke hier hapert es.

Oder habe ich die Konvertierung ...(char* szFirstLine, char* szSecondLine) des Funktionaufrufes grundsätzlich falsch gemacht ?

EDIT:
Ich habe keinen C-Komplier zum 'mal eben schnell...' So was kommt mir nicht auf die Maschine. Ich hasse C !

SirThornberry 31. Mär 2008 19:32

Re: C-Funktions-Aufruf SetText(char* szLine); nach Delphi
 
es ist die Aufrufkonvention! Da du keine spezielle angibst wird "register" verwendet und diese gibt es in C nunmal nicht also ist sie auf jeden fall falsch. Bei Register werden die Parameter wie der Name schon sagt über register übergeben. Deine DLL interpretiert nun das andere was da auf dem Stack liegt als die Paramter aber diese liegen dank register ja gar nicht dort sondern im register. Folglich siehst du Müll. Durch wahl der richtigen Aufrufconvention (per default in c = cdecl) werden die Paramter auch auf den Stack gepackt und somit sind sie auch dort vorhanden wenn die DLL vom Stack liest.

Deine Declaration ist bis auf die fehlende Convetion richtig. Und der aufruf lautet so:
Delphi-Quellcode:
VFD_SetText(PChar(Editx.Text), PChar(Edity.Text));

TERWI 31. Mär 2008 20:22

Re: C-Funktions-Aufruf SetText(char* szLine); nach Delphi
 
Klingt sinnig ! Werde ich morgen mal anschauen. Meine Frau sitzt gerade am HTPC und ich vor meiner Ballerbude und gucke wie mein Club das 1. Tor reingehämmert hat...
Ich sag wieder 'bescheid'.

TERWI 2. Apr 2008 09:11

Re: C-Funktions-Aufruf SetText(char* szLine); nach Delphi
 
Bescheid...
Positiv-Meldung: Ich hab meinen Text auf dem Display :-D
Das ABER:
Wie ich oben schon sagte, führt der Aufruf der INIT-Funktion mit stdcall zur einer Access-Violation an Adresse 00000000.
Das hatte mich bisher davon abgehalten, es auf dem HTPC zu testen. Habe ich aber nun doch einfach mal gemacht....
Mein Label1 gibt mir OK zurück und der Text kommt. Den kann ich auch so oft ändern wie ich lustig bin - keine weiteren Fehler.
Auch Programm beenden (UNINIT) gibt kein Gemaule.
Was ist nun wieder verkehrt ?
Hier mal der kurze Quelltext zu Ansicht:
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    Button2: TButton;
    Label1: TLabel;
    Label2: TLabel;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormShow(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

const
  SGVFDDLL = 'SG_VFD.dll';

// used Function from SG_VFD.dll
function VFD_Init(vfdType, dummy : integer) : bool; stdcall; external SGVFDDLL name 'iMONVFD_Init';
procedure VFD_Uninit(); stdcall; external SGVFDDLL name 'iMONVFD_Uninit';
function VFD_IsInited() : bool; stdcall; external SGVFDDLL name 'iMONVFD_IsInited';
function VFD_SetText(TXT1, TXT2 : PChar) : bool; stdcall; external SGVFDDLL name 'iMONVFD_SetText';
function VFD_SetEQ(EQdata : array of integer) : bool; stdcall; external SGVFDDLL name 'iMONVFD_SetEQ';

{
TDUMP -ee SG_VFD.DLL            
EXPORT ord:0001='iMONVFD_CheckDign'
EXPORT ord:0002='iMONVFD_Init'
EXPORT ord:0003='iMONVFD_IsInited'
EXPORT ord:0004='iMONVFD_SetAlarmOFF'
EXPORT ord:0005='iMONVFD_SetAlarmON'
EXPORT ord:0006='iMONVFD_SetAlarmON_Abs'
EXPORT ord:0007='iMONVFD_SetEQ'
EXPORT ord:0008='iMONVFD_SetText'
EXPORT ord:0009='iMONVFD_Uninit'
///////////////////////////////////////////////
//   Open VFD driver and initialize parameters.
//   Call this method, when application starts.
//   Return value informs driver is open or not
bfdType = 4 !
IMONVFD_API bool iMONVFD_Init(int vfdType, int resevered=0);

///////////////////////////////////////////////
//   Close VFD driver.
//   Call this method, when application destroyed.
IMONVFD_API void iMONVFD_Uninit(void);

///////////////////////////////////////////////
//   Check if VFD driver is opened.
IMONVFD_API bool iMONVFD_IsInited(void);

///////////////////////////////////////////////
//   Send text data to VFD. VFD supports only English character set.
IMONVFD_API bool iMONVFD_SetText(char* szFirstLine, char* szSecondLine);

///////////////////////////////////////////////
//   Send EQ data to VFD.
//   Total 16band, each band ranges from 0 to 100
//  make EQ data with integer array.
EQValue : array[0..15] of integer !
IMONVFD_API bool iMONVFD_SetEQ(int* arEQValue);
}


procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  VFD_Uninit;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
  if VFD_Init(4, 0) then
    label1.Caption := 'Init OK'
  else
    label1.Caption := 'Init failed';
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  if VFD_SetText(PChar(Edit1.Text), PChar(Edit2.Text)) then
    label2.Caption := 'Text OK'
  else
    label2.Caption := 'Text failed';
end;

end.

TERWI 2. Apr 2008 11:19

Re: C-Funktions-Aufruf SetText(char* szLine); nach Delphi
 
Liste der Anhänge anzeigen (Anzahl: 1)
... hat sich nun eigentlich von selbst erledigt.
Wenn man statt stdcall mal cdecl nimmt, klappts auch ohne Gemaule. :drunken:
Ich hab's auch mit der 16-Band-EQ-Anzeige probiert - geht auch tadellos.
Meine kleine Demo (Source, EXE und DLL) zum testen / ansehen anbei.
Funzt logo nur wirklich, wenn man auch so ein Display von Soundgrapgh hat.

@SirThornberry
Deine Anzahl von Postings lässt auf adäquate Erfahrung schließen.
Würdest du bitte auch mal hier im Forum hineinschuen ? Ab S. 3 mitte.
Dank im voraus.

:-D TERWI


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:41 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