Jump to content
Sign in to follow this  
Andreik

read file content

Recommended Posts

Andreik

Hi guys,

I want to create a dll with VC++ 2008 Express and then use it in autoit scripts but I encounter some troubles.

Dll Code

#include <stdio.h>
#include <stdlib.h>
extern "C"  __declspec(dllexport) size_t FileOpen(char *filename) {
    FILE * pFile;
    long lSize;
    char * buffer;
    size_t result;
    pFile=fopen(filename,"rb");
    fseek(pFile,0,SEEK_END);
    lSize=ftell(pFile);
    rewind(pFile);
    buffer = (char*) malloc (sizeof(char)*lSize);
    result = fread (buffer,1,lSize,pFile);
    fclose (pFile);
    free (buffer);
    return result;
}

When I compile this dll I got one warning but no errors. If I try to use this function from AutoIt script will crash.

#include <Array.au3>

$DLL = DllOpen("File.dll")
$RESULT = DllCall($DLL,"int:cdecl","FileOpen","str","Test1.dat")
DllClose($DLL)

_ArrayDisplay($RESULT)

Anyone know what I make wrong?

Edited by Andreik

When the words fail... music speaks

Share this post


Link to post
Share on other sites
Richard Robertson

Why did you mark it returning string when it actually returns an integer?

Share this post


Link to post
Share on other sites
Andreik

Hmm seems I misunderstood size_t type but you're right work well if I call the function as int:cdecl but the result after dllcall looks like that:

$Result[0] = 14
$Result[1] = "Test1.dat"

Text in Test1.dat is "this is a test" 14 chars, so there's something in $Result[0] but I don't know how to get it. Or any way to convert size_t to char?

Edited by Andreik

When the words fail... music speaks

Share this post


Link to post
Share on other sites
Valik

You need to stop and go learn C/C++ before you try writing DLLs. You are clearly missing some rather fundamental pieces of information.

Share this post


Link to post
Share on other sites
Andreik

I can learn by practicing, would be a differece if I write simple codes or DLLs? Actually I am not very interesed about C, I just try to make some speedy functions for some AutoIt scripts.


When the words fail... music speaks

Share this post


Link to post
Share on other sites
Valik

And once again the advice of a person who is self-taught and has 8+ years of experience and helped design the language you are using is ignored because clearly and demonstrably you know more than I do.

Share this post


Link to post
Share on other sites
Andreik

Don't put words in my mouth, I didn't said I am more experienced then you. If you wanna help in any way give me a tutorial.

EDIT: Finally I figured out

#include <stdio.h>
#include <stdlib.h>
extern "C"  __declspec(dllexport) char *ReadFile(char *filename) {
    FILE * pFile;
    long lSize;
    char * buffer;
    size_t result;
    pFile=fopen(filename,"rb");
    fseek(pFile,0,SEEK_END);
    lSize=ftell(pFile);
    rewind(pFile);
    buffer = (char*) malloc (sizeof(char)*lSize);
    result = fread (buffer,1,lSize,pFile);
    fclose (pFile);
    return buffer;
}

$RESULT = DllCall("FileOpen.dll","str:cdecl","ReadFile","str","test.txt")
MsgBox(0,"",RESULT[0])
Edited by Andreik

When the words fail... music speaks

Share this post


Link to post
Share on other sites
Richard Robertson

You're still not doing it right. You should never return a pointer to an allocated resource like that. If you're going to return a string, then it should be a parameter that you modify, and you return the number of characters, just like fread.

Share this post


Link to post
Share on other sites
Andreik

Ok, let's see now:

#include <stdio.h>
#include <stdlib.h>
extern "C"  __declspec(dllexport) size_t BitmapOpen(char *filename, char **buffer) {
    FILE * pFile;
    long lSize;
    size_t result;
    pFile=fopen(filename,"rb");
    fseek(pFile,0,SEEK_END);
    lSize=ftell(pFile);
    rewind(pFile);
    result = fread (buffer,1,lSize,pFile);
    fclose (pFile);
    return result;
}

Looks better?

Edited by Andreik

When the words fail... music speaks

Share this post


Link to post
Share on other sites
Richard Robertson

Almost. Buffer should only be a single layer pointer.

Share this post


Link to post
Share on other sites
Andreik

And I think to call this from AutoIt I need to create a stuct and pass the pointer of struct as buffer parameter, right?


When the words fail... music speaks

Share this post


Link to post
Share on other sites
Richard Robertson

Yes.

Share this post


Link to post
Share on other sites
Andreik

Thanks man, understood until now. One more question: can I know in a smart way how big should be the buffer to can create a properly struct?


When the words fail... music speaks

Share this post


Link to post
Share on other sites
Richard Robertson

There are three methodologies to buffer sizes.

1. Allocate a buffer that is large enough it could contain any possible data you will read. (Most typical)

2. Make a function call to see how much you need, then allocate it.

3. Use a dynamic system that allocates more memory as more is put into it. (Most expensive)

Share this post


Link to post
Share on other sites
Andreik

No.2 sounds pretty good. I will try this one. Thanks a lot man.


When the words fail... music speaks

Share this post


Link to post
Share on other sites
Andreik

Richard, I have just one more question. Am I missing something, "rb" doesn't mean read binary, why my result isn't binary?

Bitmap.dll

extern "C"  __declspec(dllexport) size_t BitmapOpen(char *filename, char *buffer) {
    FILE * pFile;
    long lSize;
    size_t result;
    pFile=fopen(filename,"rb");
    fseek(pFile,0,SEEK_END);
    lSize=ftell(pFile);
    rewind(pFile);
    result = fread (buffer,1,lSize,pFile);
    fclose (pFile);
    return result;
}

extern "C"  __declspec(dllexport) long BitmapBuffer(char *filename) {
    FILE * pFile;
    long lSize;
    pFile=fopen(filename,"rb");
    fseek(pFile,0,SEEK_END);
    lSize=ftell(pFile);
    fclose (pFile);
    return lSize;
}

Bitmap.au3

$BMP = BitmapOpen("test.bmp")
If @error Then
    MsgBox(0,"Error",@error)
Else
    MsgBox(0,"",$BMP)
EndIf

Func BitmapOpen($PATH)
    Local $BUFFER_SIZE, $BITMAP, $STRUCT
    Local $BUFFER_SIZE = DllCall("Bitmap.dll","long:cdecl","BitmapBuffer","str",$PATH)
    If @error Then
        SetError(1)
    Else
        $STRUCT = DllStructCreate("char [" & $BUFFER_SIZE[0] & "]")
        $BITMAP = DllCall("Bitmap.dll","int:cdecl","BitmapOpen","str",$PATH,"ptr",DllStructGetPtr($STRUCT))
        If @error Then
            $STRUCT = 0
            SetError(2)
        Else
            Return DllStructGetData($STRUCT,1)
        EndIf
    EndIf
EndFunc

When the words fail... music speaks

Share this post


Link to post
Share on other sites
Richard Robertson

You've provided me with no error context. I have no idea what your problem is.

Share this post


Link to post
Share on other sites
trancexx

It's too obvious. Doesn't even deserve a comment.


♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites
Andreik

If is so obvious, enlighten me. :unsure:


When the words fail... music speaks

Share this post


Link to post
Share on other sites
trancexx

If I wanted to do that I would have already.

You wrote the code, right? If you don't know why something happens then there could be a problem with you and your logic or knowledge and overall understanding of the programming process.

Once again, it's too obvious.


♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.