将二进制数据从Qt / C ++ DLL传递到Delphi宿主应用程序

时间:2012-09-07 06:37:36

标签: c++ delphi qt dll qimage

在程序中我想在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 Side中我使用此代码来使用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中编写它有很多原因。实际上,原始函数从设备中获取了一个screenShot并在主内存中处理它。因此,我希望将此图像字节发送到Delphi,以便在TImage上显示它,而不是将其保存在硬盘和类似的存储器上。在本主题中,我刚刚创建了一个简单的类似函数,用于简单的调试和可测试性。是否有可能通过为此问题编写一个真正的简单代码来帮助我?非常感谢你。 (-_-)

2 个答案:

答案 0 :(得分:5)

更直接的是使用PByte aka ^ Byte,而不是PByteArray。 虽然TByteArray是静态类型,但仍然使用数组会增加使用动态数组的随机错误风险。


不要使用PChar - 它会在第1个零字节处停止。图片不是字符串,它可以包含数百个零。

您应该将长度作为单独的变量/函数发送。 int QImage :: byteCount()const http://qt-project.org/doc/qt-4.8/qimage.html#byteCount


请编辑你的问题。你在询问比特或constbits吗?那些是不同的属性!


此外:

您应该在编译器,C ++和Pascal中学习“调用约定”。 你最好能够在Assembler级别跟踪它。

尝试在Pascal代码中使用“cdecl”指令标记该过程,或者在C和Pascal代码中使用“stdcall”指令。

尝试使用FreePascal中的h2pas实用程序进行自动转换。


现在最好 - 在这里放弃Qt 。使Qt桥只读取PNG文件是非常奇怪和脆弱的。有许多本地Delphi库支持PNG。几个例子:

答案 1 :(得分:2)

问题解决了。 (^ _ ^)

解决它:

在Qt Side:

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 Side:

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;

Thanx再次为“Arioch The”和“”David Heffernan“”。 (^ _ ^)