Problem calling extern(C) function

AuoroP via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon Dec 15 08:14:07 PST 2014


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





More information about the Digitalmars-d-learn mailing list