问题
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