digitalmars.D.learn - Problem calling extern(C) function
- AuoroP via Digitalmars-d-learn (114/114) Dec 15 2014 I'm pretty sure my problem isn't my code but how I've built the
- Adam D. Ruppe (10/14) Dec 15 2014 Without looking too closely, this sets off an alarm to me: C's
- AuoroP via Digitalmars-d-learn (7/24) Dec 15 2014 Adam D. Ruppe, I have two words for you: thank you!!! I just changed jpe...
I'm pretty sure my problem isn't my code but how I've built the
lib. The problem is I'm calling external C code and I am getting
valid data out of it but /some/ of my arguments to it is
corrupted.
A common thread in this newsgroup seems to be people calling
Extern(Windows). I don't that is me because I call with
extern(C) my .lst names are not mangled that way:
_tjDecompressHeader2, _tjGetErrorStr, _tjInitDecompress.
Even if you can't help, Thanks for reading this far!
This message is kinda long so here's a TOC
The code
The output
DLL code:
You WANT to be in this mess?
-------=-------=---------------=---------------=-------=-------
The code:
extern(C) tjhandle tjInitDecompress();
extern(C) int tjDecompressHeader2
(
tjhandle handle,
void* jpegBuf,
ulong jpegSize,
int* width,
int* height,
int* jpegSubsamp
);
extern(C) char* tjGetErrorStr();
import std.conv: to;
import std.file: exists, read;
import std.stdio: writeln;
tjhandle dHandle = tjInitDecompress();
writeln("dHandle: ", dHandle);
int width, height, subsamp;
void[] buffer = read("testimg.jpg");
writeln("buffer.ptr: ", buffer.ptr);
writeln("buffer.length: ", buffer.length);
writeln("&width: ", &width);
writeln("&height: ", &height);
writeln("&subsamp: ", &subsamp);
if
(
0 >
tjDecompressHeader2
(
dHandle,
buffer.ptr,
buffer.length,
&width,
&height,
&subsamp
)
)
{
writeln( to!string( tjGetErrorStr() ) );
writeln("testimg.jpg gets me ", buffer.length, "bytes.");
write("width: ", width);
write(" height: ", height);
writeln("subsamp: ", subsamp);
}
-------=-------=---------------=---------------=-------=-------
The output:
dHandle: 5E09F0
buffer.ptr: 2340000
buffer.length: 5764
&width: 18FDC4
&height: 18FDC8
&subsamp: 18FDCC
tjDecompressHeader2(): Invalid argument
testimg.jpg gets me 5764bytes.
width: 0 height: 0subsamp: 0
-------=-------=---------------=---------------=-------=-------
DLL code:
If you wanted to look in the DLL code, it is online here:
https://github.com/LibVNC/libvncserver/blob/master/common/turbojpeg.c
DLLEXPORT int DLLCALL tjDecompressHeader2(tjhandle handle,
unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height,
int *jpegSubsamp)
{
int retval=0;
getinstance(handle);
if((this->init&DECOMPRESS)==0)
_throw("tjDecompressHeader2(): Instance has not been initialized for
decompression");
if
(
jpegBuf==NULL ||
jpegSize<=0 ||
width==NULL ||
height==NULL||
jpegSubsamp==NULL
)
_throw("tjDecompressHeader2(): Invalid argument");
// .
// .
// .
}
-------=-------=---------------=---------------=-------=-------
You WANT to be in this mess?
If you want to play with this problem yourself then I'll help you recreate it.
I'm using 1.3.1 libjpeg-turbo which can be found here:
http://sourceforge.net/projects/libjpeg-turbo/files/1.3.1/libjpeg-turbo-1.3.1-vc.exe/download
I've gotten working .lib files out of the folders lib and bin
Getting a .lib from the DLL in bin is much more straightforward:
IMPLIB /s libTurboJPEG.lib turbojpeg.dll
LIB -l libTurboJPEG.lib
Getting a .lib from lib is tricky but the following gets you turbojpeg.omf.lib:
COFFIMPLIB turbojpeg.lib turbojpeg.omf.lib
ECHO LIB -l turbojpeg.omf.lib
I've tried to use both .lib files and their behavior is the same.
Next up is trying the GCC version with the same recipes:
http://sourceforge.net/projects/libjpeg-turbo/files/1.3.1/libjpeg-turbo-1.3.1-gcc.exe/download
The behavior is unchanged.
____________________________________________________________
FREE 3D EARTH SCREENSAVER - Watch the Earth right on your desktop!
Check it out at http://www.inbox.com/earth
Dec 15 2014
On Monday, 15 December 2014 at 17:48:32 UTC, AuoroP via Digitalmars-d-learn wrote:ulong jpegSize,Without looking too closely, this sets off an alarm to me: C's long and D's long are not really compatible because C's long has variable size and D's long is 64 bit. I'd say try "import core.stdc.config;" and replace all instances of ulong with c_ulong and all instances of long with c_long when interfacing with C.DLLEXPORT int DLLCALL tjDecompressHeader2(tjhandle handle, unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height,yeah the D long is 32 bits longer than the C function expects, so every argument after it is offset by that amount.
Dec 15 2014
Thank you!!! All I have to do is-----Original Message----- From: digitalmars-d-learn puremagic.com Sent: Mon, 15 Dec 2014 17:54:51 +0000 To: digitalmars-d-learn puremagic.com Subject: Re: Problem calling extern(C) function On Monday, 15 December 2014 at 17:48:32 UTC, AuoroP via Digitalmars-d-learn wrote:Adam D. Ruppe, I have two words for you: thank you!!! I just changed jpegSize from ulong to uint and it worked! I think I had given up so I really cannot express the joy you've given me so thank you again! ____________________________________________________________ Can't remember your password? Do you need a strong and secure password? Use Password manager! It stores your passwords & protects your account. Check it out at http://mysecurelogon.com/managerulong jpegSize,Without looking too closely, this sets off an alarm to me: C's long and D's long are not really compatible because C's long has variable size and D's long is 64 bit. I'd say try "import core.stdc.config;" and replace all instances of ulong with c_ulong and all instances of long with c_long when interfacing with C.
Dec 15 2014









"Adam D. Ruppe" <destructionator gmail.com> 