AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Paradoxes verhalten beim Aufruf einer C++ DLL aus Delphi
Thema durchsuchen
Ansicht
Themen-Optionen

Paradoxes verhalten beim Aufruf einer C++ DLL aus Delphi

Ein Thema von dust258 · begonnen am 4. Nov 2010 · letzter Beitrag vom 17. Nov 2010
Antwort Antwort
dust258

Registriert seit: 18. Aug 2008
62 Beiträge
 
#1

Paradoxes verhalten beim Aufruf einer C++ DLL aus Delphi

  Alt 4. Nov 2010, 12:46
Hallo Leute,
ich beschäftige mich im Moment mit der dll-Programmierung unter C++. Mir ist allerdings aufgefallen das von alle Integer-Werten, die ich von Delphi aus in meine DLL übergebe, immer 1 abgezogen wird...
Ich habe also die Funktion in einem Testprojekt nachgestellt, und auch hier tritt der "Fehler" auf. Kann mir das Jemand erklären?

Hier mein Delphi Testprojekt:
Delphi-Quellcode:
unit u_FormAufruf;

interface

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

  type
    TSecSigner_AssignDocuments =
    function( inArrDocs : Array of PChar;
            inIDocCount : Integer)
          : Integer; cdecl;
type
  TFormMain = class(TForm)
    Button1: TButton;
    reDisplay: TRichEdit;
    edDllName: TEdit;
    edDllFunktion: TEdit;
    lbDllName: TLabel;
    lbDllFunktion: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    fLibHandle: THandle;
    SecSigner_AssignDocuments : TSecSigner_AssignDocuments;
    function loadSecSignerLibrary: Boolean;
  public
    { Public-Deklarationen }
  end;

var
  FormMain: TFormMain;

implementation

{$R *.dfm}

procedure TFormMain.Button1Click(Sender: TObject);
var
  lArrDocs : Array of PChar;
  lICount,
  lIResult,
  I: Integer;
begin

  SetLength(lArrDocs, 4);
  lArrDocs[0] := 'test1';
  lArrDocs[1] := 'test2';
  lArrDocs[2] := 'test3';
  lArrDocs[3] := 'test4';

  if loadSecSignerLibrary then
  try
    if Assigned(SecSigner_AssignDocuments) then
    begin
      lICount := Length(lArrDocs);
      for I := 0 to Length(lArrDocs) - 1 do
      begin
        reDisplay.Lines.Add('-'+lArrDocs[i]);
      end;
      reDisplay.Lines.Add('Übergabe Count: '+IntToStr(lICount));
      lIResult := SecSigner_AssignDocuments(lArrDocs, lICount); //Hier Hat lICount den Wert 4
      reDisplay.Lines.Add('Result: '+IntToStr(lIResult));
    end else
      reDisplay.Lines.Add('Funktion nicht gefunden');
  finally
    freeLibrary(fLibHandle);
  end;
end;

function TFormMain.loadSecSignerLibrary: Boolean;
begin
  Result := true;
  try
    fLibHandle := loadLibrary(PChar(edDllName.text));
    if fLibHandle <> 0 then
    begin
      @SecSigner_AssignDocuments := getProcAddress(fLibHandle, PChar(edDllFunktion.Text));
      reDisplay.Lines.Add('getProcAddress erfolgreich');
    end else
    begin
      Result := false;
      reDisplay.Lines.Add('DLL nicht gefunden');
    end;
  except
    Result := false;
  end;
end;

end.
und die C++ DLL:
Code:
#include "stdafx.h"
#include <windows.h>
#include "DllTest.h"
#include <TCHAR.H>
#include <stdio.h>

#pragma comment (lib, "user32.lib")



extern "C" __declspec(dllexport)int AssignDocuments(char* inArrFilenames[], int inIDocCount);
int AssignDocuments(char* inArrFilenames[], int inIDocCount)
{
   int i = inIDocCount;
   TCHAR str1[100];
   _stprintf(str1, _T("inIDocCount = %d"), inIDocCount);

   TCHAR str2[100];
   _stprintf(str2, _T("i in C++ = %d"), i); //Hier gibt die MessageBox 3 Aus

   MessageBox ( NULL, str1, str2, MB_OK);
   return i;
}
Das Projekt befindet sich außerdem im Anhang.
Angehängte Dateien
Dateityp: zip DllTest.zip (1,60 MB, 2x aufgerufen)
  Mit Zitat antworten Zitat
Benutzerbild von Assarbad
Assarbad

Registriert seit: 8. Okt 2010
Ort: Frankfurt am Main
1.234 Beiträge
 
#2

AW: Paradoxes verhalten beim Aufruf einer C++ DLL aus Delphi

  Alt 4. Nov 2010, 12:55
Erstmal:
Code:
int const i = inIDocCount; // konstant deklarieren
Guck mal ob das was ändert. Sollte zwar nicht, aber ist ohnehin die bessere Vorgehensweise.

Ansonsten sehe ich, daß die DLL eine .NET-Assembly ist. Hmm. Aber sollte nix ausmachen. Aber dennoch, warum? Der Code ist doch reines C++, warum als managed Kompilieren? Wo ist da der Vorteil für dich?

Und vor allem ist für mich nicht ersichtlich wo das passieren woll, was du sagst:

Code:
  .method assembly static modopt([mscorlib]System.Runtime.CompilerServices.CallConvCdecl) int32 AssignDocuments(modopt([mscorlib]System.Runtime.CompilerServices.IsConst) modopt([mscorlib]System.Runtime.CompilerServices.IsConst) modopt([mscorlib]System.Runtime.CompilerServices.IsSignUnspecifiedByte) int8** inArrFilenames, int32 inIDocCount)
  {
    .maxstack 4
    .locals (valuetype <CppImplementationDetails>.$ArrayType$$$BY0GE@_W V0,
             valuetype <CppImplementationDetails>.$ArrayType$$$BY0GE@_W V1)
    ldloca.s 1
    ldsflda modopt([mscorlib]System.Runtime.CompilerServices.IsConst) valuetype <CppImplementationDetails>.$ArrayType$$$BY0BB@$$CB_W ??_C@_1CC@JEIJDBMP@?$AAi?$AAn?$AAI?$AAD?$AAo?$AAc?$AAC?$AAo?$AAu?$AAn?$AAt?$AA?5?$AA?$DN?$AA?5?$AA?$CF?$AAd?$AA?$AA@
    ldarg.1
    call modopt([mscorlib]System.Runtime.CompilerServices.CallConvCdecl) int32 _swprintf(char*, modopt([mscorlib]System.Runtime.CompilerServices.IsConst) char*, int32)
    pop
    ldloca.s 0
    ldsflda modopt([mscorlib]System.Runtime.CompilerServices.IsConst) valuetype <CppImplementationDetails>.$ArrayType$$$BY0O@$$CB_W ??_C@_1BM@LPOBPDGL@?$AAi?$AA?5?$AAi?$AAn?$AA?5?$AAC?$AA?$CL?$AA?$CL?$AA?5?$AA?$DN?$AA?5?$AA?$CF?$AAd?$AA?$AA@
    ldarg.1
    call modopt([mscorlib]System.Runtime.CompilerServices.CallConvCdecl) int32 _swprintf(char*, modopt([mscorlib]System.Runtime.CompilerServices.IsConst) char*, int32)
    pop
    ldc.i4.0
    ldloca.s 1
    ldloca.s 0
    ldc.i4.0
    call T0x6000055
    pop
    ldarg.1
    ret
  }
Oliver
"... aber vertrauen Sie uns, die Physik stimmt." (Prof. Harald Lesch)
  Mit Zitat antworten Zitat
Dezipaitor

Registriert seit: 14. Apr 2003
Ort: Stuttgart
1.701 Beiträge
 
Delphi 7 Professional
 
#3

AW: Paradoxes verhalten beim Aufruf einer C++ DLL aus Delphi

  Alt 4. Nov 2010, 13:19
Array of PChar ist nicht kompatibel mit
Code:
char* inArrFilenames[]
.
Benutze stattdessen

Delphi-Quellcode:
  type
    TSecSigner_AssignDocuments =
    function( inArrDocs : PPChar;
            inIDocCount : Integer)
          : Integer; cdecl;
und

lIResult := SecSigner_AssignDocuments(@lArrDocs, lICount);
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)
  Mit Zitat antworten Zitat
dust258

Registriert seit: 18. Aug 2008
62 Beiträge
 
#4

AW: Paradoxes verhalten beim Aufruf einer C++ DLL aus Delphi

  Alt 17. Nov 2010, 08:38
Hab mal Zeit gefunden das zu testen.

@Assarbad
Stimmt, in Zukunft werde ich sowas konstant deklarieren. Danke für den Tipp.
Ich habe nur die Logik aus der dll genommen um ein möglichst einfaches Beispiel zu liefern. In der "echten" Funktion benötige ich .Net Features.

@Dezipaitor
Das war es, jetzt funktioniert es ohne Probleme. D A N K E
  Mit Zitat antworten Zitat
Antwort Antwort


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 04:47 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