Sign in to follow this  
Followers 0
Andreik

read file content

24 posts in this topic

#1 ·  Posted (edited)

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



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

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

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

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

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

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

#7 ·  Posted (edited)

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

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

#9 ·  Posted (edited)

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

Almost. Buffer should only be a single layer pointer.

Share this post


Link to post
Share on other sites

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

Yes.

Share this post


Link to post
Share on other sites

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

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

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

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

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

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


♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

If is so obvious, enlighten me. :unsure:


When the words fail... music speaks

Share this post


Link to post
Share on other sites

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  
Followers 0