3

プログラムでは、Delphi で QImage.bits() を使用したいと考えています。そのため、Qt で dll を作成しました。以下にリストされているdllソースコード:

test.h:

  #ifndef TEST_H
    #define TEST_H

    #include "test_global.h"


    extern "C"{
    TESTSHARED_EXPORT uchar* testFunc();
    }


    #endif // TEST_H

test.cpp:

 #include "test.h"
#include <QtGui>

QImage image;

uchar* testFunc(){
    image.load("c:\\1.png","PNG");
    return (uchar*)image.constBits();
}

Delphi 側では、Qt dll を使用するために次のコードを使用します。

    function testFunc(): PByteArray; external 'test.dll';
// ...

procedure TForm3.Button1Click(Sender: TObject);
var
  bStream: TBytesStream;
  P: PByteArray;
  Size: Cardinal;
begin
  P := testFunc;
  Size := Length(PAnsiChar(P)); // AnsiChar = 1 Byte
  bStream := TBytesStream.Create();
  try
    bStream.Write(P[0], Size); // Works Fine (^_^)
    bStream.Position := 0;
    bStream.SaveToFile('c:\scr.txt');
  finally
    bStream.Free;
  end;
end;

dll 関数を呼び出すと、データが返されません! 手伝って頂けますか?

更新 1: 実際の状況では、私の Qt 関数は非常に複雑で、多くの理由で Delphi で記述できません。実際、元の機能はデバイスからスクリーンショットを取得し、メインメモリでそれを処理します。その結果、このイメージ バイトを Delphi に送信して TImage に表示し、ハードディスクや同様のメモリに保存しません。このトピックでは、単純なデバッグとテスト容易性のために単純な同様の関数を作成しました。この問題に対して真にシンプルなコードを書くことで私を助けることは可能ですか? どうもありがとう。(-_-)

4

2 に答える 2

5

もっと簡単なのは、PByteArray ではなく PByte 別名 ^Byte を使用することです。TByteArray は静的型ですが、それでも配列を使用すると、動的配列を使用する場合と同様に、ランダムなタイプミスのリスクが追加されます。


PChar を使用しないでください。最初の 0 バイトで停止します。ピクチャは文字列ではありません。数百のゼロをかなり含むことができます。

長さを別の変数/関数として送信する必要があります。 int QImage::byteCount () const http://qt-project.org/doc/qt-4.8/qimage.html#byteCount


質問を編集してください。ビットまたは constbits について質問していますか? それらは異なるプロパティです!


また:

コンパイラ、C++、および Pascal の「呼び出し規約」について学ぶ必要があります。アセンブラレベルで追跡できる方がよいでしょう。

Pascal コードで「cdecl」ディレクティブを使用するか、C コードと Pascal コードの両方で「stdcall」ディレクティブを使用して、そのプロシージャをマークしてみてください。

自動変換のために FreePascal の h2pas ユーティリティを試してください。


ここで Qt をドロップしてください。PNG ファイルを読み取るためだけに Qt ブリッジを作成するのは、非常に奇妙で壊れやすいものです。PNG をサポートするネイティブ Delphi ライブラリが多数あります。いくつかの例:

于 2012-09-07T07:18:28.033 に答える
2

問題が解決しました。(^_^)

それを解決するために:

Qt側:

test.h:

#ifndef TEST_H
#define TEST_H

#include "test_global.h"


extern "C"{
TESTSHARED_EXPORT char* testFunc(int &a);
}


#endif // TEST_H

test.cpp:

#include "test.h"
#include <QtGui>

QImage image;
QByteArray ba;


char* testFunc(int &a){
    image.load("c:\\2.png","PNG");
    QBuffer buffer(&ba);
    buffer.open(QIODevice::WriteOnly);
    image.save(&buffer,"PNG");
    a = ba.size();
    return ba.data();
}

Delphi 側:

function testFunc(var aByteCount: DWORD): PByte;cdecl external 'test.dll';

// ...
var
  bStream: TBytesStream;
  Size: DWORD;
procedure TForm3.Button1Click(Sender: TObject);
var
  P: PByte;
  s: TStringList;
begin
  Caption := '0';
  P := testFunc(Size);
  bStream := TBytesStream.Create();
  try
    bStream.Write(P[0], Size);
    bStream.Position := 0;
    bStream.SaveToFile('c:\my.png');
  finally
    Caption := IntToStr(Size);
  end;
end;

「Arioch The」と「David Heffernan」に感謝します。(^_^)

于 2012-09-07T13:09:58.450 に答える