Passing binary data from Qt/C++ DLL into Delphi host application

╄→尐↘猪︶ㄣ 提交于 2020-01-14 14:08:13

问题


In a Program I want to uses QImage.bits() in Delphi. So, in Qt I was created a dll. the dll Source Code Listed in below:

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();
}

and in the Delphi Side I use this code for using 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;

when I call dll function no any data returned! can you help me?

Update 1: In real situation my Qt function is very complex and I can't write it in Delphi for many reasons. In fact orginal function taked a screenShot from a device and work on It in Main Memory. and as a result I want send this image bytes to Delphi for Show It on a TImage whit no save It on Hard Disk and similar memories. and in this topic I just created a simple similar function for simple debugging and testability. Is It Possible to help me by Writing a True Simple code for this problem? thanx a lot for you. (-_-)


回答1:


More straightforward would be using PByte aka ^Byte, not PByteArray. Though TByteArray is static type, still using arrays adds a risk of random typo like using dynamic arrays.


Don't use PChar - it would stop on 1st zero byte. Picture is not a string, it can fairly contains hundreds of zeroes.

You should send length as a separate variable/function. int QImage::byteCount () const http://qt-project.org/doc/qt-4.8/qimage.html#byteCount


Edit you question please. Are you asking about bits or constbits ? those are different properties!


Also:

You should learn about "calling conventions" in you compilers, C++ and Pascal. You'd better be able to track it on Assembler level.

try marking that procedure with "cdecl" directive in Pascal code, or maybe with "stdcall" directive in both C and Pascal code.

Try h2pas utility from FreePascal for auto-conversion.


Now best of all - drop Qt here. Making Qt bridges just to read PNG file is very weird and fragile. There are a number of native Delphi libraries with PNG support. Few examples:

  • Soft Gems: http://www.soft-gems.net/index.php/libs/graphicex-library
  • Vampyre: http://imaginglib.sf.net



回答2:


Problem solved. (^_^)

For solving It:

In 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();
}

In 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 again for "Arioch The" and ""David Heffernan"". (^_^)



来源:https://stackoverflow.com/questions/12312968/passing-binary-data-from-qt-c-dll-into-delphi-host-application

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!