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